From [[a list|http://www.brainpickings.org/index.php/2012/08/10/10-rules-for-students-and-teachers-john-cage-corita-kent/]] titled ''Some Rules for Students and Teachers'', attributed to John Cage. The list, however, originates from celebrated artist and educator Sister Corita Kent. !!!!A couple of "preliminaries" * The [[list on Brainpickings|http://www.brainpickings.org/index.php/2012/08/10/10-rules-for-students-and-teachers-john-cage-corita-kent/]] has 10 rules, but I won't mention all of them; some of them I strongly resonate with (see below :) and some of them I don't (so go see [[Brainpickings|http://www.brainpickings.org/index.php/2012/08/10/10-rules-for-students-and-teachers-john-cage-corita-kent/]] :) . ** Therefore, I like the title "__Some__ Rules...", and I suspect that -- and hence the last sentence at the end of the Hints at the end of the rules -- there should be new rules next week. * The list is titled "for teachers and students", but aren't we all BOTH one or the other at ANY given point in time, provided we pay attention and are present (as we teach, we learn) - see, for example, my modification of rule #3. ** Therefore, I like the extension "Rules for Life" (regardless of what your "official role" (teacher, student) is). So, ** ''RULE TWO'': General duties of a student — pull everything out of your teacher; pull everything out of your fellow students. *** Sage advice. I think it should actually be "your teachers" (plural) ** ''RULE THREE'': General duties of a teacher — pull everything out of your students. *** and fellow teachers (my extension) ** ''RULE FOUR'': Consider everything an experiment. *** and (unlike the conventional scientific belief/definition of an experiment) a unique, non-repeatable one at that. *** There is something both liberating AND grave about this view: on one hand, it's an experiment, so it's not about "success or failure" (i.e., like in science, if it's a "good experiment" you learn from it either way -- see rule #6). On the other hand, since it's a one-time experiment/experience (as is ALL of life itself), it had better be a "good one"! ** ''RULE SIX'': Nothing is a mistake. There’s no win and no fail, there’s only make. *** Tied to rule #4 - if it's a "good experiment" you learn from it either way. *** If by "make" it means "learn and improve", then I wholeheartedly agree. ** ''RULE SEVEN'': The only rule is work. If you work it will lead to something. It’s the people who do all of the work all of the time who eventually catch on to things. *** like in rule #6 - If by "work" it means "learn and improve", then I wholeheartedly agree. ** ''RULE EIGHT'': Don’t try to create and analyze at the same time. They’re different processes. *** Excellent and useful observation, as well as advice for effective and deep learning. I found this to be especially relevant when thinking about the differences between the emphases [[Doug Lemov|http://teachlikeachampion.com/blog/]] puts on effective teacher/classroom practices, and [[Deborah Ball|http://www-personal.umich.edu/~dball/presentations/index.html]]'s: **** In a nutshell, my view is that Lemov is focusing on (49) Techniques and "tools to create a positive and lifelong impact on student learning" (from his book "Teach Like a Champion"), whereas Ball talks about the potent and essential combination (to learning) of pedagogy (and techniques) AND content/subject matter knowledge. ***** My perception of Lemov's approach (formed by reading his book and watching the accompanying video clips of teachers in classrooms) is one with traces of "militantism" and "student indoctrination" (so as not to say "robotization" - see for example his SLANT technique: Sit up, Listen, Ask and answer questions, Nod your head, Trace the speaker) ***** Ball, in my mind" is "wiser" by realizing the deeper truth, and advocating the need for teachers to practice and improve on both fronts: the tools and techniques (i.e. pedagogy) which are different from Lemov's) and content/domain knowledge, as well as thinking, analyzing, discussing, debating, experimenting, and communicating processes and procedures (which we want to encourage and teach). ** ''RULE NINE'': Be happy whenever you can manage it. Enjoy yourself. It’s lighter than you think. *** What can I say? A Zen sparkle coming from a nun (Sister Corita Kent) - regardless of where you find wisdom, it's always refreshing :) *** Echoing rules #4 and #6 - experiment; be playful; enjoy it. But also, make things count; make them "good ones". ** (my addition:) ''RULE TEN'': Ask questions. The expand your mind and universe. And as John O’Donohue had said: [[questions are like lanterns|John O’Donohue - questions]]. ** ''HINTS'': Always be around. Come or go to everything. Always go to classes. Read anything you can get your hands on. Look at movies carefully, often. Save everything -- it might come in handy later. There should be new rules next week.
''#83'' The notion of cyclical time is crucial to Native Americans. For them, sacred events recur again and again in a pattern that repeats the cycles of the celestial sphere. Time does not progress along a linear path but moves in a cyclical manner so as to provide an enclosure within which events occur. Past, present, and future all exist together because the cycles turn continually upon themselves. The progression of time along a developmental path was a concept foreign to Native Americans until the Europeans forced them into history. CRAZY INJUNS
show
no
{
"tiddlers": {
"$:/Acknowledgements": {
"title": "$:/Acknowledgements",
"text": "TiddlyWiki incorporates code from these fine OpenSource projects:\n\n* [[The Stanford Javascript Crypto Library|http://bitwiseshiftleft.github.io/sjcl/]]\n* [[The Jasmine JavaScript Test Framework|http://pivotal.github.io/jasmine/]]\n* [[Normalize.css by Nicolas Gallagher|http://necolas.github.io/normalize.css/]]\n\nAnd media from these projects:\n\n* World flag icons from [[Wikipedia|http://commons.wikimedia.org/wiki/Category:SVG_flags_by_country]]\n"
},
"$:/core/copyright.txt": {
"title": "$:/core/copyright.txt",
"type": "text/plain",
"text": "TiddlyWiki created by Jeremy Ruston, (jeremy [at] jermolene [dot] com)\n\nCopyright (c) 2004-2007, Jeremy Ruston\nCopyright (c) 2007-2018, UnaMesa Association\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this\n list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\n this list of conditions and the following disclaimer in the documentation\n and/or other materials provided with the distribution.\n\n* Neither the name of the copyright holder nor the names of its\n contributors may be used to endorse or promote products derived from\n this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
},
"$:/core/icon": {
"title": "$:/core/icon",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\"><path d=\"M64 0l54.56 32v64L64 128 9.44 96V32L64 0zm21.127 95.408c-3.578-.103-5.15-.094-6.974-3.152l-1.42.042c-1.653-.075-.964-.04-2.067-.097-1.844-.07-1.548-1.86-1.873-2.8-.52-3.202.687-6.43.65-9.632-.014-1.14-1.593-5.17-2.157-6.61-1.768.34-3.546.406-5.34.497-4.134-.01-8.24-.527-12.317-1.183-.8 3.35-3.16 8.036-1.21 11.44 2.37 3.52 4.03 4.495 6.61 4.707 2.572.212 3.16 3.18 2.53 4.242-.55.73-1.52.864-2.346 1.04l-1.65.08c-1.296-.046-2.455-.404-3.61-.955-1.93-1.097-3.925-3.383-5.406-5.024.345.658.55 1.938.24 2.53-.878 1.27-4.665 1.26-6.4.47-1.97-.89-6.73-7.162-7.468-11.86 1.96-3.78 4.812-7.07 6.255-11.186-3.146-2.05-4.83-5.384-4.61-9.16l.08-.44c-3.097.59-1.49.37-4.82.628-10.608-.032-19.935-7.37-14.68-18.774.34-.673.664-1.287 1.243-.994.466.237.4 1.18.166 2.227-3.005 13.627 11.67 13.732 20.69 11.21.89-.25 2.67-1.936 3.905-2.495 2.016-.91 4.205-1.282 6.376-1.55 5.4-.63 11.893 2.276 15.19 2.37 3.3.096 7.99-.805 10.87-.615 2.09.098 4.143.483 6.16 1.03 1.306-6.49 1.4-11.27 4.492-12.38 1.814.293 3.213 2.818 4.25 4.167 2.112-.086 4.12.46 6.115 1.066 3.61-.522 6.642-2.593 9.833-4.203-3.234 2.69-3.673 7.075-3.303 11.127.138 2.103-.444 4.386-1.164 6.54-1.348 3.507-3.95 7.204-6.97 7.014-1.14-.036-1.805-.695-2.653-1.4-.164 1.427-.81 2.7-1.434 3.96-1.44 2.797-5.203 4.03-8.687 7.016-3.484 2.985 1.114 13.65 2.23 15.594 1.114 1.94 4.226 2.652 3.02 4.406-.37.58-.936.785-1.54 1.01l-.82.11zm-40.097-8.85l.553.14c.694-.27 2.09.15 2.83.353-1.363-1.31-3.417-3.24-4.897-4.46-.485-1.47-.278-2.96-.174-4.46l.02-.123c-.582 1.205-1.322 2.376-1.72 3.645-.465 1.71 2.07 3.557 3.052 4.615l.336.3z\" fill-rule=\"evenodd\"/></svg>"
},
"$:/core/images/add-comment": {
"title": "$:/core/images/add-comment",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-add-comment tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\"><path d=\"M56 56H36a8 8 0 1 0 0 16h20v20a8 8 0 1 0 16 0V72h20a8 8 0 1 0 0-16H72V36a8 8 0 1 0-16 0v20zm-12.595 58.362c-6.683 7.659-20.297 12.903-36.006 12.903-2.196 0-4.35-.102-6.451-.3 9.652-3.836 17.356-12.24 21.01-22.874C8.516 94.28 0 79.734 0 63.5 0 33.953 28.206 10 63 10s63 23.953 63 53.5S97.794 117 63 117c-6.841 0-13.428-.926-19.595-2.638z\" fill-rule=\"evenodd\"/></svg>"
},
"$:/core/images/advanced-search-button": {
"title": "$:/core/images/advanced-search-button",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-advanced-search-button tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M74.5651535,87.9848361 C66.9581537,93.0488876 57.8237115,96 48,96 C21.490332,96 0,74.509668 0,48 C0,21.490332 21.490332,0 48,0 C74.509668,0 96,21.490332 96,48 C96,57.8541369 93.0305793,67.0147285 87.9377231,74.6357895 L122.284919,108.982985 C125.978897,112.676963 125.973757,118.65366 122.284271,122.343146 C118.593975,126.033442 112.613238,126.032921 108.92411,122.343793 L74.5651535,87.9848361 Z M48,80 C65.673112,80 80,65.673112 80,48 C80,30.326888 65.673112,16 48,16 C30.326888,16 16,30.326888 16,48 C16,65.673112 30.326888,80 48,80 Z\"></path>\n <circle cx=\"48\" cy=\"48\" r=\"8\"></circle>\n <circle cx=\"28\" cy=\"48\" r=\"8\"></circle>\n <circle cx=\"68\" cy=\"48\" r=\"8\"></circle>\n </g>\n</svg>"
},
"$:/core/images/auto-height": {
"title": "$:/core/images/auto-height",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-auto-height tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <path d=\"M67.9867828,114.356363 L67.9579626,99.8785426 C67.9550688,98.4248183 67.1636987,97.087107 65.8909901,96.3845863 L49.9251455,87.5716209 L47.992126,95.0735397 L79.8995411,95.0735397 C84.1215894,95.0735397 85.4638131,89.3810359 81.686497,87.4948823 L49.7971476,71.5713518 L48.0101917,79.1500092 L79.992126,79.1500092 C84.2093753,79.1500092 85.5558421,73.4676733 81.7869993,71.5753162 L49.805065,55.517008 L48.0101916,63.0917009 L79.9921259,63.0917015 C84.2035118,63.0917016 85.5551434,57.4217887 81.7966702,55.5218807 L65.7625147,47.4166161 L67.9579705,50.9864368 L67.9579705,35.6148245 L77.1715737,44.8284272 C78.7336709,46.3905243 81.2663308,46.3905243 82.8284279,44.8284271 C84.390525,43.2663299 84.390525,40.7336699 82.8284278,39.1715728 L66.8284271,23.1715728 C65.2663299,21.6094757 62.73367,21.6094757 61.1715729,23.1715729 L45.1715729,39.1715729 C43.6094757,40.73367 43.6094757,43.26633 45.1715729,44.8284271 C46.73367,46.3905243 49.26633,46.3905243 50.8284271,44.8284271 L59.9579705,35.6988837 L59.9579705,50.9864368 C59.9579705,52.495201 60.806922,53.8755997 62.1534263,54.5562576 L78.1875818,62.6615223 L79.9921261,55.0917015 L48.0101917,55.0917009 C43.7929424,55.0917008 42.4464755,60.7740368 46.2153183,62.6663939 L78.1972526,78.7247021 L79.992126,71.1500092 L48.0101917,71.1500092 C43.7881433,71.1500092 42.4459197,76.842513 46.2232358,78.7286665 L78.1125852,94.6521971 L79.8995411,87.0735397 L47.992126,87.0735397 C43.8588276,87.0735397 42.4404876,92.5780219 46.0591064,94.5754586 L62.024951,103.388424 L59.9579785,99.8944677 L59.9867142,114.32986 L50.8284271,105.171573 C49.26633,103.609476 46.73367,103.609476 45.1715729,105.171573 C43.6094757,106.73367 43.6094757,109.26633 45.1715729,110.828427 L61.1715729,126.828427 C62.73367,128.390524 65.2663299,128.390524 66.8284271,126.828427 L82.8284278,110.828427 C84.390525,109.26633 84.390525,106.73367 82.8284279,105.171573 C81.2663308,103.609476 78.7336709,103.609476 77.1715737,105.171573 L67.9867828,114.356363 L67.9867828,114.356363 Z M16,20 L112,20 C114.209139,20 116,18.209139 116,16 C116,13.790861 114.209139,12 112,12 L16,12 C13.790861,12 12,13.790861 12,16 C12,18.209139 13.790861,20 16,20 L16,20 Z\"></path>\n</svg>"
},
"$:/core/images/blank": {
"title": "$:/core/images/blank",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-blank tc-image-button\" viewBox=\"0 0 128 128\" width=\"22pt\" height=\"22pt\"></svg>"
},
"$:/core/images/bold": {
"title": "$:/core/images/bold",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-bold tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M41.1456583,51.8095238 L41.1456583,21.8711485 L67.4985994,21.8711485 C70.0084159,21.8711485 72.4285598,22.0802967 74.7591036,22.4985994 C77.0896475,22.9169022 79.1512515,23.6638602 80.9439776,24.7394958 C82.7367036,25.8151314 84.170863,27.3090474 85.2464986,29.2212885 C86.3221342,31.1335296 86.859944,33.5835518 86.859944,36.5714286 C86.859944,41.9496067 85.2465147,45.8337882 82.0196078,48.2240896 C78.792701,50.614391 74.6694929,51.8095238 69.6498599,51.8095238 L41.1456583,51.8095238 Z M13,0 L13,128 L75.0280112,128 C80.7647346,128 86.3519803,127.28292 91.789916,125.848739 C97.2278517,124.414559 102.068139,122.203563 106.310924,119.215686 C110.553709,116.22781 113.929959,112.373506 116.439776,107.652661 C118.949592,102.931816 120.204482,97.3445701 120.204482,90.8907563 C120.204482,82.8832466 118.262391,76.0411115 114.378151,70.3641457 C110.493911,64.6871798 104.607883,60.7133634 96.719888,58.442577 C102.456611,55.6937304 106.788968,52.1680887 109.717087,47.8655462 C112.645206,43.5630037 114.109244,38.1849062 114.109244,31.7310924 C114.109244,25.7553389 113.123259,20.7357813 111.151261,16.6722689 C109.179262,12.6087565 106.400578,9.35201972 102.815126,6.90196078 C99.2296739,4.45190185 94.927196,2.68908101 89.907563,1.61344538 C84.8879301,0.537809748 79.3305627,0 73.2352941,0 L13,0 Z M41.1456583,106.128852 L41.1456583,70.9915966 L71.8011204,70.9915966 C77.896389,70.9915966 82.7964334,72.3958776 86.5014006,75.2044818 C90.2063677,78.0130859 92.0588235,82.7039821 92.0588235,89.2773109 C92.0588235,92.6237329 91.4911355,95.3725383 90.3557423,97.5238095 C89.2203491,99.6750808 87.6965548,101.378145 85.7843137,102.633053 C83.8720726,103.887961 81.661077,104.784311 79.1512605,105.322129 C76.641444,105.859947 74.0121519,106.128852 71.2633053,106.128852 L41.1456583,106.128852 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/cancel-button": {
"title": "$:/core/images/cancel-button",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-cancel-button tc-image-button\" viewBox=\"0 0 128 128\" width=\"22pt\" height=\"22pt\">\n\t<g fill-rule=\"evenodd\">\n\t <path d=\"M64,76.3137085 L47.0294734,93.2842351 C43.9038742,96.4098343 38.8399231,96.4084656 35.7157288,93.2842712 C32.5978915,90.166434 32.5915506,85.0947409 35.7157649,81.9705266 L52.6862915,65 L35.7157649,48.0294734 C32.5901657,44.9038742 32.5915344,39.8399231 35.7157288,36.7157288 C38.833566,33.5978915 43.9052591,33.5915506 47.0294734,36.7157649 L64,53.6862915 L80.9705266,36.7157649 C84.0961258,33.5901657 89.1600769,33.5915344 92.2842712,36.7157288 C95.4021085,39.833566 95.4084494,44.9052591 92.2842351,48.0294734 L75.3137085,65 L92.2842351,81.9705266 C95.4098343,85.0961258 95.4084656,90.1600769 92.2842712,93.2842712 C89.166434,96.4021085 84.0947409,96.4084494 80.9705266,93.2842351 L64,76.3137085 Z M64,129 C99.346224,129 128,100.346224 128,65 C128,29.653776 99.346224,1 64,1 C28.653776,1 1.13686838e-13,29.653776 1.13686838e-13,65 C1.13686838e-13,100.346224 28.653776,129 64,129 Z M64,113 C90.509668,113 112,91.509668 112,65 C112,38.490332 90.509668,17 64,17 C37.490332,17 16,38.490332 16,65 C16,91.509668 37.490332,113 64,113 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/chevron-down": {
"title": "$:/core/images/chevron-down",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-chevron-down tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n\t<g fill-rule=\"evenodd\" transform=\"translate(64.000000, 40.500000) rotate(-270.000000) translate(-64.000000, -40.500000) translate(-22.500000, -26.500000)\">\n <path d=\"M112.743107,112.12741 C111.310627,113.561013 109.331747,114.449239 107.145951,114.449239 L27.9777917,114.449239 C23.6126002,114.449239 20.0618714,110.904826 20.0618714,106.532572 C20.0618714,102.169214 23.6059497,98.6159054 27.9777917,98.6159054 L99.2285381,98.6159054 L99.2285381,27.365159 C99.2285381,22.9999675 102.77295,19.4492387 107.145205,19.4492387 C111.508562,19.4492387 115.061871,22.993317 115.061871,27.365159 L115.061871,106.533318 C115.061871,108.71579 114.175869,110.694669 112.743378,112.127981 Z\" transform=\"translate(67.561871, 66.949239) rotate(-45.000000) translate(-67.561871, -66.949239) \"></path>\n <path d=\"M151.35638,112.12741 C149.923899,113.561013 147.94502,114.449239 145.759224,114.449239 L66.5910645,114.449239 C62.225873,114.449239 58.6751442,110.904826 58.6751442,106.532572 C58.6751442,102.169214 62.2192225,98.6159054 66.5910645,98.6159054 L137.841811,98.6159054 L137.841811,27.365159 C137.841811,22.9999675 141.386223,19.4492387 145.758478,19.4492387 C150.121835,19.4492387 153.675144,22.993317 153.675144,27.365159 L153.675144,106.533318 C153.675144,108.71579 152.789142,110.694669 151.356651,112.127981 Z\" transform=\"translate(106.175144, 66.949239) rotate(-45.000000) translate(-106.175144, -66.949239) \"></path>\n\t</g>\n</svg>"
},
"$:/core/images/chevron-left": {
"title": "$:/core/images/chevron-left",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-chevron-left tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\" version=\"1.1\">\n <g fill-rule=\"evenodd\" transform=\"translate(92.500000, 64.000000) rotate(-180.000000) translate(-92.500000, -64.000000) translate(6.000000, -3.000000)\">\n <path d=\"M112.743107,112.12741 C111.310627,113.561013 109.331747,114.449239 107.145951,114.449239 L27.9777917,114.449239 C23.6126002,114.449239 20.0618714,110.904826 20.0618714,106.532572 C20.0618714,102.169214 23.6059497,98.6159054 27.9777917,98.6159054 L99.2285381,98.6159054 L99.2285381,27.365159 C99.2285381,22.9999675 102.77295,19.4492387 107.145205,19.4492387 C111.508562,19.4492387 115.061871,22.993317 115.061871,27.365159 L115.061871,106.533318 C115.061871,108.71579 114.175869,110.694669 112.743378,112.127981 Z\" transform=\"translate(67.561871, 66.949239) rotate(-45.000000) translate(-67.561871, -66.949239) \"></path>\n <path d=\"M151.35638,112.12741 C149.923899,113.561013 147.94502,114.449239 145.759224,114.449239 L66.5910645,114.449239 C62.225873,114.449239 58.6751442,110.904826 58.6751442,106.532572 C58.6751442,102.169214 62.2192225,98.6159054 66.5910645,98.6159054 L137.841811,98.6159054 L137.841811,27.365159 C137.841811,22.9999675 141.386223,19.4492387 145.758478,19.4492387 C150.121835,19.4492387 153.675144,22.993317 153.675144,27.365159 L153.675144,106.533318 C153.675144,108.71579 152.789142,110.694669 151.356651,112.127981 Z\" transform=\"translate(106.175144, 66.949239) rotate(-45.000000) translate(-106.175144, -66.949239) \"></path>\n </g>\n</svg>"
},
"$:/core/images/chevron-right": {
"title": "$:/core/images/chevron-right",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-chevron-right tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\" transform=\"translate(-48.000000, -3.000000)\">\n <path d=\"M112.743107,112.12741 C111.310627,113.561013 109.331747,114.449239 107.145951,114.449239 L27.9777917,114.449239 C23.6126002,114.449239 20.0618714,110.904826 20.0618714,106.532572 C20.0618714,102.169214 23.6059497,98.6159054 27.9777917,98.6159054 L99.2285381,98.6159054 L99.2285381,27.365159 C99.2285381,22.9999675 102.77295,19.4492387 107.145205,19.4492387 C111.508562,19.4492387 115.061871,22.993317 115.061871,27.365159 L115.061871,106.533318 C115.061871,108.71579 114.175869,110.694669 112.743378,112.127981 Z\" transform=\"translate(67.561871, 66.949239) rotate(-45.000000) translate(-67.561871, -66.949239) \"></path>\n <path d=\"M151.35638,112.12741 C149.923899,113.561013 147.94502,114.449239 145.759224,114.449239 L66.5910645,114.449239 C62.225873,114.449239 58.6751442,110.904826 58.6751442,106.532572 C58.6751442,102.169214 62.2192225,98.6159054 66.5910645,98.6159054 L137.841811,98.6159054 L137.841811,27.365159 C137.841811,22.9999675 141.386223,19.4492387 145.758478,19.4492387 C150.121835,19.4492387 153.675144,22.993317 153.675144,27.365159 L153.675144,106.533318 C153.675144,108.71579 152.789142,110.694669 151.356651,112.127981 Z\" transform=\"translate(106.175144, 66.949239) rotate(-45.000000) translate(-106.175144, -66.949239) \"></path>\n </g>\n</svg>"
},
"$:/core/images/chevron-up": {
"title": "$:/core/images/chevron-up",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-chevron-up tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n\t<g fill-rule=\"evenodd\" transform=\"translate(64.000000, 89.500000) rotate(-90.000000) translate(-64.000000, -89.500000) translate(-22.500000, 22.500000)\">\n <path d=\"M112.743107,112.12741 C111.310627,113.561013 109.331747,114.449239 107.145951,114.449239 L27.9777917,114.449239 C23.6126002,114.449239 20.0618714,110.904826 20.0618714,106.532572 C20.0618714,102.169214 23.6059497,98.6159054 27.9777917,98.6159054 L99.2285381,98.6159054 L99.2285381,27.365159 C99.2285381,22.9999675 102.77295,19.4492387 107.145205,19.4492387 C111.508562,19.4492387 115.061871,22.993317 115.061871,27.365159 L115.061871,106.533318 C115.061871,108.71579 114.175869,110.694669 112.743378,112.127981 Z\" transform=\"translate(67.561871, 66.949239) rotate(-45.000000) translate(-67.561871, -66.949239) \"></path>\n <path d=\"M151.35638,112.12741 C149.923899,113.561013 147.94502,114.449239 145.759224,114.449239 L66.5910645,114.449239 C62.225873,114.449239 58.6751442,110.904826 58.6751442,106.532572 C58.6751442,102.169214 62.2192225,98.6159054 66.5910645,98.6159054 L137.841811,98.6159054 L137.841811,27.365159 C137.841811,22.9999675 141.386223,19.4492387 145.758478,19.4492387 C150.121835,19.4492387 153.675144,22.993317 153.675144,27.365159 L153.675144,106.533318 C153.675144,108.71579 152.789142,110.694669 151.356651,112.127981 Z\" transform=\"translate(106.175144, 66.949239) rotate(-45.000000) translate(-106.175144, -66.949239) \"></path>\n\t</g>\n</svg>"
},
"$:/core/images/clone-button": {
"title": "$:/core/images/clone-button",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-clone-button tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M32.2650915,96 L32.2650915,120.002359 C32.2650915,124.419334 35.8432884,128 40.2627323,128 L120.002359,128 C124.419334,128 128,124.421803 128,120.002359 L128,40.2627323 C128,35.8457573 124.421803,32.2650915 120.002359,32.2650915 L96,32.2650915 L96,48 L108.858899,48 C110.519357,48 111.853018,49.3405131 111.853018,50.9941198 L111.853018,108.858899 C111.853018,110.519357 110.512505,111.853018 108.858899,111.853018 L50.9941198,111.853018 C49.333661,111.853018 48,110.512505 48,108.858899 L48,96 L32.2650915,96 Z\"></path>\n <path d=\"M40,56 L32.0070969,56 C27.5881712,56 24,52.418278 24,48 C24,43.5907123 27.5848994,40 32.0070969,40 L40,40 L40,32.0070969 C40,27.5881712 43.581722,24 48,24 C52.4092877,24 56,27.5848994 56,32.0070969 L56,40 L63.9929031,40 C68.4118288,40 72,43.581722 72,48 C72,52.4092877 68.4151006,56 63.9929031,56 L56,56 L56,63.9929031 C56,68.4118288 52.418278,72 48,72 C43.5907123,72 40,68.4151006 40,63.9929031 L40,56 Z M7.9992458,0 C3.58138434,0 0,3.5881049 0,7.9992458 L0,88.0007542 C0,92.4186157 3.5881049,96 7.9992458,96 L88.0007542,96 C92.4186157,96 96,92.4118951 96,88.0007542 L96,7.9992458 C96,3.58138434 92.4118951,0 88.0007542,0 L7.9992458,0 Z M19.0010118,16 C17.3435988,16 16,17.336731 16,19.0010118 L16,76.9989882 C16,78.6564012 17.336731,80 19.0010118,80 L76.9989882,80 C78.6564012,80 80,78.663269 80,76.9989882 L80,19.0010118 C80,17.3435988 78.663269,16 76.9989882,16 L19.0010118,16 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/close-all-button": {
"title": "$:/core/images/close-all-button",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-close-all-button tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\" transform=\"translate(-23.000000, -23.000000)\">\n <path d=\"M43,131 L22.9976794,131 C18.5827987,131 15,127.418278 15,123 C15,118.590712 18.5806831,115 22.9976794,115 L43,115 L43,94.9976794 C43,90.5827987 46.581722,87 51,87 C55.4092877,87 59,90.5806831 59,94.9976794 L59,115 L79.0023206,115 C83.4172013,115 87,118.581722 87,123 C87,127.409288 83.4193169,131 79.0023206,131 L59,131 L59,151.002321 C59,155.417201 55.418278,159 51,159 C46.5907123,159 43,155.419317 43,151.002321 L43,131 Z\" transform=\"translate(51.000000, 123.000000) rotate(-45.000000) translate(-51.000000, -123.000000) \"></path>\n <path d=\"M43,59 L22.9976794,59 C18.5827987,59 15,55.418278 15,51 C15,46.5907123 18.5806831,43 22.9976794,43 L43,43 L43,22.9976794 C43,18.5827987 46.581722,15 51,15 C55.4092877,15 59,18.5806831 59,22.9976794 L59,43 L79.0023206,43 C83.4172013,43 87,46.581722 87,51 C87,55.4092877 83.4193169,59 79.0023206,59 L59,59 L59,79.0023206 C59,83.4172013 55.418278,87 51,87 C46.5907123,87 43,83.4193169 43,79.0023206 L43,59 Z\" transform=\"translate(51.000000, 51.000000) rotate(-45.000000) translate(-51.000000, -51.000000) \"></path>\n <path d=\"M115,59 L94.9976794,59 C90.5827987,59 87,55.418278 87,51 C87,46.5907123 90.5806831,43 94.9976794,43 L115,43 L115,22.9976794 C115,18.5827987 118.581722,15 123,15 C127.409288,15 131,18.5806831 131,22.9976794 L131,43 L151.002321,43 C155.417201,43 159,46.581722 159,51 C159,55.4092877 155.419317,59 151.002321,59 L131,59 L131,79.0023206 C131,83.4172013 127.418278,87 123,87 C118.590712,87 115,83.4193169 115,79.0023206 L115,59 Z\" transform=\"translate(123.000000, 51.000000) rotate(-45.000000) translate(-123.000000, -51.000000) \"></path>\n <path d=\"M115,131 L94.9976794,131 C90.5827987,131 87,127.418278 87,123 C87,118.590712 90.5806831,115 94.9976794,115 L115,115 L115,94.9976794 C115,90.5827987 118.581722,87 123,87 C127.409288,87 131,90.5806831 131,94.9976794 L131,115 L151.002321,115 C155.417201,115 159,118.581722 159,123 C159,127.409288 155.419317,131 151.002321,131 L131,131 L131,151.002321 C131,155.417201 127.418278,159 123,159 C118.590712,159 115,155.419317 115,151.002321 L115,131 Z\" transform=\"translate(123.000000, 123.000000) rotate(-45.000000) translate(-123.000000, -123.000000) \"></path>\n </g>\n</svg>"
},
"$:/core/images/close-button": {
"title": "$:/core/images/close-button",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-close-button tc-image-button\" viewBox=\"0 0 128 128\" width=\"22pt\" height=\"22pt\">\n <g fill-rule=\"evenodd\">\n <path d=\"M65.0864256,75.4091629 L14.9727349,125.522854 C11.8515951,128.643993 6.78104858,128.64922 3.65685425,125.525026 C0.539017023,122.407189 0.5336324,117.334539 3.65902635,114.209145 L53.7727171,64.0954544 L3.65902635,13.9817637 C0.537886594,10.8606239 0.532659916,5.79007744 3.65685425,2.6658831 C6.77469148,-0.451954124 11.8473409,-0.457338747 14.9727349,2.66805521 L65.0864256,52.7817459 L115.200116,2.66805521 C118.321256,-0.453084553 123.391803,-0.458311231 126.515997,2.6658831 C129.633834,5.78372033 129.639219,10.8563698 126.513825,13.9817637 L76.4001341,64.0954544 L126.513825,114.209145 C129.634965,117.330285 129.640191,122.400831 126.515997,125.525026 C123.39816,128.642863 118.32551,128.648248 115.200116,125.522854 L65.0864256,75.4091629 L65.0864256,75.4091629 Z\"></path>\n </g>\n</svg>\n"
},
"$:/core/images/close-others-button": {
"title": "$:/core/images/close-others-button",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-close-others-button tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M64,128 C99.346224,128 128,99.346224 128,64 C128,28.653776 99.346224,0 64,0 C28.653776,0 0,28.653776 0,64 C0,99.346224 28.653776,128 64,128 Z M64,112 C90.509668,112 112,90.509668 112,64 C112,37.490332 90.509668,16 64,16 C37.490332,16 16,37.490332 16,64 C16,90.509668 37.490332,112 64,112 Z M64,96 C81.673112,96 96,81.673112 96,64 C96,46.326888 81.673112,32 64,32 C46.326888,32 32,46.326888 32,64 C32,81.673112 46.326888,96 64,96 Z M64,80 C72.836556,80 80,72.836556 80,64 C80,55.163444 72.836556,48 64,48 C55.163444,48 48,55.163444 48,64 C48,72.836556 55.163444,80 64,80 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/copy-clipboard": {
"title": "$:/core/images/copy-clipboard",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-copy-clipboard tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n\t<g fill-rule=\"evenodd\">\n\t\t<rect x=\"40\" y=\"40\" width=\"33\" height=\"8\" rx=\"4\"></rect>\n\t\t<rect x=\"40\" y=\"82\" width=\"17\" height=\"8\" rx=\"4\"></rect>\n\t\t<rect x=\"40\" y=\"54\" width=\"17\" height=\"8\" rx=\"4\"></rect>\n\t\t<rect x=\"40\" y=\"96\" width=\"33\" height=\"8\" rx=\"4\"></rect>\n\t\t<rect x=\"40\" y=\"68\" width=\"12\" height=\"8\" rx=\"4\"></rect>\n\t\t<path d=\"M40,16 L23.9992458,16 C19.5813843,16 16,19.5907123 16,24 C16,24.0016363 16.0000005,24.0032725 16.0000015,24.0049086 C16.0000005,24.0065441 16,24.0081803 16,24.0098166 L16,119.990183 C16,119.99182 16.0000005,119.993456 16.0000015,119.995092 C16.0000005,119.996727 16,119.998364 16,120 C16,124.409288 19.5813843,128 23.9992458,128 L104.000754,128 C106.205061,128 108.203844,127.105595 109.652065,125.659342 C111.102424,124.21251 112,122.214511 112,120.007595 L112,103.992405 C112,99.5776607 108.418278,96 104,96 C99.5907123,96 96,99.5783218 96,103.992405 L96,112 L32,112 L32,32 L96,32 L96,40.0075946 C96,44.4223393 99.581722,48 104,48 C108.409288,48 112,44.4216782 112,40.0075946 L112,23.9924054 C112,21.7851587 111.104671,19.7871591 109.657101,18.3409203 C108.203844,16.8944047 106.205061,16 104.000754,16 L88,16 C88,11.5907123 84.4151006,8 79.9929031,8 L48.0070969,8 C43.5881712,8 40,11.581722 40,16 Z M44,14.9958262 C44,12.7889923 45.7964248,11 48.0000255,11 L79.9999745,11 C82.2091276,11 84,12.7965212 84,14.9958262 L84,19.0041738 C84,21.2110077 82.2035752,23 79.9999745,23 L48.0000255,23 C45.7908724,23 44,21.2034788 44,19.0041738 L44,14.9958262 Z\"></path>\n\t\t<rect x=\"62\" y=\"64\" width=\"66\" height=\"16\" rx=\"8\"></rect>\n\t\t<path d=\"M60.6568542,85.6568542 L76.6568542,69.6568543 L65.3431458,69.6568542 L81.3431458,85.6568542 C84.4673401,88.7810486 89.5326599,88.7810486 92.6568542,85.6568542 C95.7810486,82.5326599 95.7810486,77.4673401 92.6568542,74.3431458 L76.6568542,58.3431458 C73.5326599,55.2189514 68.4673401,55.2189514 65.3431458,58.3431457 L49.3431458,74.3431457 C46.2189514,77.4673401 46.2189514,82.5326599 49.3431457,85.6568542 C52.4673401,88.7810486 57.5326599,88.7810486 60.6568542,85.6568542 L60.6568542,85.6568542 Z\" transform=\"translate(71.000000, 72.000000) rotate(-90.000000) translate(-71.000000, -72.000000) \"></path>\n\t</g>\n</svg>"
},
"$:/core/images/delete-button": {
"title": "$:/core/images/delete-button",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-delete-button tc-image-button\" viewBox=\"0 0 128 128\" width=\"22pt\" height=\"22pt\">\n <g fill-rule=\"evenodd\" transform=\"translate(12.000000, 0.000000)\">\n <rect x=\"0\" y=\"11\" width=\"105\" height=\"16\" rx=\"8\"></rect>\n <rect x=\"28\" y=\"0\" width=\"48\" height=\"16\" rx=\"8\"></rect>\n <rect x=\"8\" y=\"16\" width=\"16\" height=\"112\" rx=\"8\"></rect>\n <rect x=\"8\" y=\"112\" width=\"88\" height=\"16\" rx=\"8\"></rect>\n <rect x=\"80\" y=\"16\" width=\"16\" height=\"112\" rx=\"8\"></rect>\n <rect x=\"56\" y=\"16\" width=\"16\" height=\"112\" rx=\"8\"></rect>\n <rect x=\"32\" y=\"16\" width=\"16\" height=\"112\" rx=\"8\"></rect>\n </g>\n</svg>"
},
"$:/core/images/done-button": {
"title": "$:/core/images/done-button",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-done-button tc-image-button\" viewBox=\"0 0 128 128\" width=\"22pt\" height=\"22pt\">\n <g fill-rule=\"evenodd\">\n <path d=\"M3.52445141,76.8322939 C2.07397484,75.3828178 1.17514421,73.3795385 1.17514421,71.1666288 L1.17514421,23.1836596 C1.17514421,18.7531992 4.75686621,15.1751442 9.17514421,15.1751442 C13.5844319,15.1751442 17.1751442,18.7606787 17.1751442,23.1836596 L17.1751442,63.1751442 L119.173716,63.1751442 C123.590457,63.1751442 127.175144,66.7568662 127.175144,71.1751442 C127.175144,75.5844319 123.592783,79.1751442 119.173716,79.1751442 L9.17657227,79.1751442 C6.96796403,79.1751442 4.9674142,78.279521 3.51911285,76.8315312 Z\" id=\"Rectangle-285\" transform=\"translate(64.175144, 47.175144) rotate(-45.000000) translate(-64.175144, -47.175144) \"></path>\n </g>\n</svg>"
},
"$:/core/images/down-arrow": {
"title": "$:/core/images/down-arrow",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-down-arrow tc-image-button\" viewBox=\"0 0 128 128\" width=\"22pt\" height=\"22pt\">\n <path d=\"M109.35638,81.3533152 C107.923899,82.7869182 105.94502,83.6751442 103.759224,83.6751442 L24.5910645,83.6751442 C20.225873,83.6751442 16.6751442,80.1307318 16.6751442,75.7584775 C16.6751442,71.3951199 20.2192225,67.8418109 24.5910645,67.8418109 L95.8418109,67.8418109 L95.8418109,-3.40893546 C95.8418109,-7.77412698 99.3862233,-11.3248558 103.758478,-11.3248558 C108.121835,-11.3248558 111.675144,-7.78077754 111.675144,-3.40893546 L111.675144,75.7592239 C111.675144,77.9416955 110.789142,79.9205745 109.356651,81.3538862 Z\" transform=\"translate(64.175144, 36.175144) rotate(45.000000) translate(-64.175144, -36.175144) \"></path>\n</svg>"
},
"$:/core/images/download-button": {
"title": "$:/core/images/download-button",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-download-button tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path class=\"tc-image-download-button-ring\" d=\"M64,128 C99.346224,128 128,99.346224 128,64 C128,28.653776 99.346224,0 64,0 C28.653776,0 0,28.653776 0,64 C0,99.346224 28.653776,128 64,128 Z M64,112 C90.509668,112 112,90.509668 112,64 C112,37.490332 90.509668,16 64,16 C37.490332,16 16,37.490332 16,64 C16,90.509668 37.490332,112 64,112 Z\"/><path d=\"M34.3496823,66.4308767 L61.2415823,93.634668 C63.0411536,95.4551107 65.9588502,95.4551107 67.7584215,93.634668 L94.6503215,66.4308767 C96.4498928,64.610434 96.4498928,61.6588981 94.6503215,59.8384554 C93.7861334,58.9642445 92.6140473,58.4731195 91.3919019,58.4731195 L82.9324098,58.4731195 C80.3874318,58.4731195 78.3243078,56.3860674 78.3243078,53.8115729 L78.3243078,38.6615466 C78.3243078,36.0870521 76.2611837,34 73.7162058,34 L55.283798,34 C52.7388201,34 50.675696,36.0870521 50.675696,38.6615466 L50.675696,38.6615466 L50.675696,53.8115729 C50.675696,56.3860674 48.612572,58.4731195 46.0675941,58.4731195 L37.608102,58.4731195 C35.063124,58.4731195 33,60.5601716 33,63.134666 C33,64.3709859 33.4854943,65.5566658 34.3496823,66.4308767 L34.3496823,66.4308767 Z\"/></g></svg>"
},
"$:/core/images/edit-button": {
"title": "$:/core/images/edit-button",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-edit-button tc-image-button\" viewBox=\"0 0 128 128\" width=\"22pt\" height=\"22pt\">\n <g fill-rule=\"evenodd\">\n <path d=\"M116.870058,45.3431458 L108.870058,45.3431458 L108.870058,45.3431458 L108.870058,61.3431458 L116.870058,61.3431458 L116.870058,45.3431458 Z M124.870058,45.3431458 L127.649881,45.3431458 C132.066101,45.3431458 135.656854,48.9248678 135.656854,53.3431458 C135.656854,57.7524334 132.07201,61.3431458 127.649881,61.3431458 L124.870058,61.3431458 L124.870058,45.3431458 Z M100.870058,45.3431458 L15.6638275,45.3431458 C15.5064377,45.3431458 15.3501085,45.3476943 15.1949638,45.3566664 L15.1949638,45.3566664 C15.0628002,45.3477039 14.928279,45.3431458 14.7913977,45.3431458 C6.68160973,45.3431458 -8.34314575,53.3431458 -8.34314575,53.3431458 C-8.34314575,53.3431458 6.85614548,61.3431458 14.7913977,61.3431458 C14.9266533,61.3431458 15.0596543,61.3384973 15.190398,61.3293588 C15.3470529,61.3385075 15.5049057,61.3431458 15.6638275,61.3431458 L100.870058,61.3431458 L100.870058,45.3431458 L100.870058,45.3431458 Z\" transform=\"translate(63.656854, 53.343146) rotate(-45.000000) translate(-63.656854, -53.343146) \"></path>\n <path d=\"M35.1714596,124.189544 C41.9594858,123.613403 49.068777,121.917633 58.85987,118.842282 C60.6854386,118.268877 62.4306907,117.705515 65.1957709,116.802278 C81.1962861,111.575575 87.0734839,109.994907 93.9414474,109.655721 C102.29855,109.242993 107.795169,111.785371 111.520478,118.355045 C112.610163,120.276732 115.051363,120.951203 116.97305,119.861518 C118.894737,118.771832 119.569207,116.330633 118.479522,114.408946 C113.146151,105.003414 104.734907,101.112919 93.5468356,101.66546 C85.6716631,102.054388 79.4899908,103.716944 62.7116783,109.197722 C59.9734132,110.092199 58.2519873,110.64787 56.4625698,111.20992 C37.002649,117.322218 25.6914684,118.282267 16.8654804,112.957098 C14.9739614,111.815848 12.5154166,112.424061 11.3741667,114.31558 C10.2329168,116.207099 10.84113,118.665644 12.7326489,119.806894 C19.0655164,123.627836 26.4866335,124.926678 35.1714596,124.189544 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/erase": {
"title": "$:/core/images/erase",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-erase tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M60.0870401,127.996166 L123.102318,64.980888 C129.636723,58.4464827 129.629513,47.8655877 123.098967,41.3350425 L99.4657866,17.7018617 C92.927448,11.1635231 82.3486358,11.1698163 75.8199411,17.698511 L4.89768189,88.6207702 C-1.63672343,95.1551755 -1.6295126,105.736071 4.90103262,112.266616 L20.6305829,127.996166 L60.0870401,127.996166 Z M25.1375576,120.682546 L10.812569,106.357558 C7.5455063,103.090495 7.54523836,97.793808 10.8048093,94.5342371 L46.2691086,59.0699377 L81.7308914,94.5317205 L55.5800654,120.682546 L25.1375576,120.682546 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/excise": {
"title": "$:/core/images/excise",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-excise tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M56,107.313709 L53.6568542,109.656854 C50.5326599,112.781049 45.4673401,112.781049 42.3431457,109.656854 C39.2189514,106.53266 39.2189514,101.46734 42.3431458,98.3431457 L58.3431458,82.3431457 C61.4673401,79.2189514 66.5326599,79.2189514 69.6568542,82.3431458 L85.6568542,98.3431458 C88.7810486,101.46734 88.7810486,106.53266 85.6568542,109.656854 C82.5326599,112.781049 77.4673401,112.781049 74.3431458,109.656854 L72,107.313708 L72,121.597798 C72,125.133636 68.418278,128 64,128 C59.581722,128 56,125.133636 56,121.597798 L56,107.313709 Z M0,40.0070969 C0,35.5848994 3.59071231,32 8,32 C12.418278,32 16,35.5881712 16,40.0070969 L16,71.9929031 C16,76.4151006 12.4092877,80 8,80 C3.581722,80 0,76.4118288 0,71.9929031 L0,40.0070969 Z M32,40.0070969 C32,35.5848994 35.5907123,32 40,32 C44.418278,32 48,35.5881712 48,40.0070969 L48,71.9929031 C48,76.4151006 44.4092877,80 40,80 C35.581722,80 32,76.4118288 32,71.9929031 L32,40.0070969 Z M80,40.0070969 C80,35.5848994 83.5907123,32 88,32 C92.418278,32 96,35.5881712 96,40.0070969 L96,71.9929031 C96,76.4151006 92.4092877,80 88,80 C83.581722,80 80,76.4118288 80,71.9929031 L80,40.0070969 Z M56,8.00709688 C56,3.58489938 59.5907123,0 64,0 C68.418278,0 72,3.58817117 72,8.00709688 L72,39.9929031 C72,44.4151006 68.4092877,48 64,48 C59.581722,48 56,44.4118288 56,39.9929031 L56,8.00709688 Z M112,40.0070969 C112,35.5848994 115.590712,32 120,32 C124.418278,32 128,35.5881712 128,40.0070969 L128,71.9929031 C128,76.4151006 124.409288,80 120,80 C115.581722,80 112,76.4118288 112,71.9929031 L112,40.0070969 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/export-button": {
"title": "$:/core/images/export-button",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-export-button tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M8.00348646,127.999999 C8.00464867,128 8.00581094,128 8.00697327,128 L119.993027,128 C122.205254,128 124.207939,127.101378 125.657096,125.651198 L125.656838,125.65759 C127.104563,124.210109 128,122.21009 128,119.999949 L128,56.0000511 C128,51.5817449 124.409288,48 120,48 C115.581722,48 112,51.5797863 112,56.0000511 L112,112 L16,112 L16,56.0000511 C16,51.5817449 12.4092877,48 8,48 C3.581722,48 7.10542736e-15,51.5797863 7.10542736e-15,56.0000511 L7.10542736e-15,119.999949 C7.10542736e-15,124.418255 3.59071231,128 8,128 C8.00116233,128 8.0023246,128 8.00348681,127.999999 Z M56.6235633,27.3113724 L47.6580188,36.2769169 C44.5333664,39.4015692 39.4634864,39.4061295 36.339292,36.2819351 C33.2214548,33.1640979 33.2173444,28.0901742 36.3443103,24.9632084 L58.9616908,2.34582788 C60.5248533,0.782665335 62.5748436,0.000361191261 64.624516,2.38225238e-14 L64.6193616,0.00151809229 C66.6695374,0.000796251595 68.7211167,0.781508799 70.2854358,2.34582788 L92.9028163,24.9632084 C96.0274686,28.0878607 96.0320289,33.1577408 92.9078345,36.2819351 C89.7899973,39.3997724 84.7160736,39.4038827 81.5891078,36.2769169 L72.6235633,27.3113724 L72.6235633,88.5669606 C72.6235633,92.9781015 69.0418413,96.5662064 64.6235633,96.5662064 C60.2142756,96.5662064 56.6235633,92.984822 56.6235633,88.5669606 L56.6235633,27.3113724 L56.6235633,27.3113724 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/file": {
"title": "$:/core/images/file",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-file tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"nonzero\">\n <path d=\"M111.96811,30.5 L112,30.5 L112,119.999079 C112,124.417866 108.419113,128 104.000754,128 L23.9992458,128 C19.5813843,128 16,124.417687 16,119.999079 L16,8.00092105 C16,3.58213437 19.5808867,0 23.9992458,0 L81,0 L81,0.0201838424 C83.1589869,-0.071534047 85.3482153,0.707077645 86.9982489,2.35711116 L109.625176,24.9840387 C111.151676,26.510538 111.932942,28.4998414 111.96811,30.5 L111.96811,30.5 Z M81,8 L24,8 L24,120 L104,120 L104,30.5 L89.0003461,30.5 C84.5818769,30.5 81,26.9216269 81,22.4996539 L81,8 Z\"></path>\n <rect x=\"32\" y=\"36\" width=\"64\" height=\"8\" rx=\"4\"></rect>\n <rect x=\"32\" y=\"52\" width=\"64\" height=\"8\" rx=\"4\"></rect>\n <rect x=\"32\" y=\"68\" width=\"64\" height=\"8\" rx=\"4\"></rect>\n <rect x=\"32\" y=\"84\" width=\"64\" height=\"8\" rx=\"4\"></rect>\n <rect x=\"32\" y=\"100\" width=\"64\" height=\"8\" rx=\"4\"></rect>\n <rect x=\"32\" y=\"20\" width=\"40\" height=\"8\" rx=\"4\"></rect>\n </g>\n</svg>"
},
"$:/core/images/fixed-height": {
"title": "$:/core/images/fixed-height",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-fixed-height tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M60,35.6568542 L50.8284271,44.8284271 C49.26633,46.3905243 46.73367,46.3905243 45.1715729,44.8284271 C43.6094757,43.26633 43.6094757,40.73367 45.1715729,39.1715729 L61.1715729,23.1715729 C62.73367,21.6094757 65.2663299,21.6094757 66.8284271,23.1715728 L82.8284278,39.1715728 C84.390525,40.7336699 84.390525,43.2663299 82.8284279,44.8284271 C81.2663308,46.3905243 78.7336709,46.3905243 77.1715737,44.8284272 L68,35.6568539 L68,93.3431461 L77.1715737,84.1715728 C78.7336709,82.6094757 81.2663308,82.6094757 82.8284279,84.1715729 C84.390525,85.7336701 84.390525,88.2663301 82.8284278,89.8284272 L66.8284271,105.828427 C65.2663299,107.390524 62.73367,107.390524 61.1715729,105.828427 L45.1715729,89.8284271 C43.6094757,88.26633 43.6094757,85.73367 45.1715729,84.1715729 C46.73367,82.6094757 49.26633,82.6094757 50.8284271,84.1715729 L60,93.3431458 L60,35.6568542 L60,35.6568542 Z M16,116 L112,116 C114.209139,116 116,114.209139 116,112 C116,109.790861 114.209139,108 112,108 L16,108 C13.790861,108 12,109.790861 12,112 C12,114.209139 13.790861,116 16,116 L16,116 Z M16,20 L112,20 C114.209139,20 116,18.209139 116,16 C116,13.790861 114.209139,12 112,12 L16,12 C13.790861,12 12,13.790861 12,16 C12,18.209139 13.790861,20 16,20 L16,20 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/fold-all-button": {
"title": "$:/core/images/fold-all-button",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-fold-all tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <rect x=\"0\" y=\"0\" width=\"128\" height=\"16\" rx=\"8\"></rect>\n <rect x=\"0\" y=\"64\" width=\"128\" height=\"16\" rx=\"8\"></rect>\n <path d=\"M64.0292774,58.6235628 C61.9791013,58.6242848 59.9275217,57.8435723 58.3632024,56.279253 L35.7458219,33.6618725 C32.6211696,30.5372202 32.6166093,25.4673401 35.7408036,22.3431458 C38.8586409,19.2253085 43.9325646,19.2211982 47.0595304,22.348164 L64.0250749,39.3137085 L80.9906194,22.348164 C84.1152717,19.2235117 89.1851518,19.2189514 92.3093461,22.3431458 C95.4271834,25.460983 95.4312937,30.5349067 92.3043279,33.6618725 L69.6869474,56.279253 C68.1237851,57.8424153 66.0737951,58.6247195 64.0241231,58.6250809 Z\" transform=\"translate(64.024316, 39.313708) scale(1, -1) translate(-64.024316, -39.313708) \"></path>\n <path d=\"M64.0292774,123.621227 C61.9791013,123.621949 59.9275217,122.841236 58.3632024,121.276917 L35.7458219,98.6595365 C32.6211696,95.5348842 32.6166093,90.4650041 35.7408036,87.3408098 C38.8586409,84.2229725 43.9325646,84.2188622 47.0595304,87.345828 L64.0250749,104.311373 L80.9906194,87.345828 C84.1152717,84.2211757 89.1851518,84.2166154 92.3093461,87.3408098 C95.4271834,90.458647 95.4312937,95.5325707 92.3043279,98.6595365 L69.6869474,121.276917 C68.1237851,122.840079 66.0737951,123.622383 64.0241231,123.622745 Z\" transform=\"translate(64.024316, 104.311372) scale(1, -1) translate(-64.024316, -104.311372) \"></path>\n </g>\n</svg>"
},
"$:/core/images/fold-button": {
"title": "$:/core/images/fold-button",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-fold tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <rect x=\"0\" y=\"0\" width=\"128\" height=\"16\" rx=\"8\"></rect>\n <path d=\"M64.0292774,63.6235628 C61.9791013,63.6242848 59.9275217,62.8435723 58.3632024,61.279253 L35.7458219,38.6618725 C32.6211696,35.5372202 32.6166093,30.4673401 35.7408036,27.3431458 C38.8586409,24.2253085 43.9325646,24.2211982 47.0595304,27.348164 L64.0250749,44.3137085 L80.9906194,27.348164 C84.1152717,24.2235117 89.1851518,24.2189514 92.3093461,27.3431458 C95.4271834,30.460983 95.4312937,35.5349067 92.3043279,38.6618725 L69.6869474,61.279253 C68.1237851,62.8424153 66.0737951,63.6247195 64.0241231,63.6250809 Z\" transform=\"translate(64.024316, 44.313708) scale(1, -1) translate(-64.024316, -44.313708) \"></path>\n <path d=\"M64.0049614,105.998482 C61.9547853,105.999204 59.9032057,105.218491 58.3388864,103.654172 L35.7215059,81.0367916 C32.5968535,77.9121393 32.5922933,72.8422592 35.7164876,69.7180649 C38.8343248,66.6002276 43.9082485,66.5961173 47.0352144,69.7230831 L64.0007589,86.6886276 L80.9663034,69.7230831 C84.0909557,66.5984308 89.1608358,66.5938705 92.2850301,69.7180649 C95.4028673,72.8359021 95.4069777,77.9098258 92.2800119,81.0367916 L69.6626314,103.654172 C68.099469,105.217334 66.0494791,105.999639 63.999807,106 Z\" transform=\"translate(64.000000, 86.688628) scale(1, -1) translate(-64.000000, -86.688628) \"></path>\n </g>\n</svg>"
},
"$:/core/images/fold-others-button": {
"title": "$:/core/images/fold-others-button",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-fold-others tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <rect x=\"0\" y=\"56.0314331\" width=\"128\" height=\"16\" rx=\"8\"></rect>\n <path d=\"M101.657101,104.948818 C100.207918,103.498614 98.2051847,102.599976 95.9929031,102.599976 L72,102.599976 L72,78.6070725 C72,76.3964271 71.1036108,74.3936927 69.6545293,72.9441002 L69.6571005,72.9488183 C68.2079177,71.4986143 66.2051847,70.5999756 63.9929031,70.5999756 L32.0070969,70.5999756 C27.5881712,70.5999756 24,74.1816976 24,78.5999756 C24,83.0092633 27.5848994,86.5999756 32.0070969,86.5999756 L56,86.5999756 L56,110.592879 C56,112.803524 56.8963895,114.806259 58.3454713,116.255852 L58.3429,116.251133 C59.7920828,117.701337 61.7948156,118.599976 64.0070969,118.599976 L88,118.599976 L88,142.592879 C88,147.011804 91.581722,150.599976 96,150.599976 C100.409288,150.599976 104,147.015076 104,142.592879 L104,110.607072 C104,108.396427 103.103611,106.393693 101.654529,104.9441 Z\" transform=\"translate(64.000000, 110.599976) rotate(-45.000000) translate(-64.000000, -110.599976) \"></path>\n <path d=\"M101.725643,11.7488671 C100.27646,10.2986632 98.2737272,9.40002441 96.0614456,9.40002441 L72.0685425,9.40002441 L72.0685425,-14.5928787 C72.0685425,-16.8035241 71.1721533,-18.8062584 69.7230718,-20.255851 L69.725643,-20.2511329 C68.2764602,-21.7013368 66.2737272,-22.5999756 64.0614456,-22.5999756 L32.0756394,-22.5999756 C27.6567137,-22.5999756 24.0685425,-19.0182536 24.0685425,-14.5999756 C24.0685425,-10.1906879 27.6534419,-6.59997559 32.0756394,-6.59997559 L56.0685425,-6.59997559 L56.0685425,17.3929275 C56.0685425,19.6035732 56.964932,21.6063078 58.4140138,23.0559004 L58.4114425,23.0511823 C59.8606253,24.5013859 61.8633581,25.4000244 64.0756394,25.4000244 L88.0685425,25.4000244 L88.0685425,49.3929275 C88.0685425,53.8118532 91.6502645,57.4000244 96.0685425,57.4000244 C100.47783,57.4000244 104.068542,53.815125 104.068542,49.3929275 L104.068542,17.4071213 C104.068542,15.1964759 103.172153,13.1937416 101.723072,11.744149 Z\" transform=\"translate(64.068542, 17.400024) scale(1, -1) rotate(-45.000000) translate(-64.068542, -17.400024) \"></path>\n </g>\n</svg>"
},
"$:/core/images/folder": {
"title": "$:/core/images/folder",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-folder tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M55.6943257,128.000004 L7.99859666,128.000004 C3.5810937,128.000004 0,124.413822 0,119.996384 L0,48.0036243 C0,43.5833471 3.58387508,40.0000044 7.99859666,40.0000044 L16,40.0000044 L16,31.9999914 C16,27.5817181 19.5783731,24 24.0003461,24 L55.9996539,24 C60.4181231,24 64,27.5800761 64,31.9999914 L64,40.0000044 L104.001403,40.0000044 C108.418906,40.0000044 112,43.5861868 112,48.0036243 L112,59.8298353 L104,59.7475921 L104,51.9994189 C104,49.7887607 102.207895,48.0000044 99.9972215,48.0000044 L56,48.0000044 L56,36.0000255 C56,33.7898932 54.2072328,32 51.9957423,32 L28.0042577,32 C25.7890275,32 24,33.7908724 24,36.0000255 L24,48.0000044 L12.0027785,48.0000044 C9.78987688,48.0000044 8,49.7906032 8,51.9994189 L8,116.00059 C8,118.211248 9.79210499,120.000004 12.0027785,120.000004 L58.7630167,120.000004 L55.6943257,128.000004 L55.6943257,128.000004 Z\"></path>\n <path d=\"M23.8728955,55.5 L119.875702,55.5 C124.293205,55.5 126.87957,59.5532655 125.650111,64.5630007 L112.305967,118.936999 C111.077582,123.942356 106.497904,128 102.083183,128 L6.08037597,128 C1.66287302,128 -0.923492342,123.946735 0.305967145,118.936999 L13.650111,64.5630007 C14.878496,59.5576436 19.4581739,55.5 23.8728955,55.5 L23.8728955,55.5 L23.8728955,55.5 Z M25.6530124,64 L113.647455,64 C115.858129,64 117.151473,66.0930612 116.538306,68.6662267 L105.417772,115.333773 C104.803671,117.910859 102.515967,120 100.303066,120 L12.3086228,120 C10.0979492,120 8.8046054,117.906939 9.41777189,115.333773 L20.5383062,68.6662267 C21.1524069,66.0891409 23.4401107,64 25.6530124,64 L25.6530124,64 L25.6530124,64 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/full-screen-button": {
"title": "$:/core/images/full-screen-button",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-full-screen-button tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g>\n <g>\n <path d=\"M5.29777586e-31,8 C1.59060409e-15,3.581722 3.581722,0 8,0 L40,0 C44.418278,0 48,3.581722 48,8 C48,12.418278 44.418278,16 40,16 L16,16 L16,40 C16,44.418278 12.418278,48 8,48 C3.581722,48 -3.55271368e-15,44.418278 0,40 L3.55271368e-15,8 Z\"></path>\n </g>\n <g transform=\"translate(104.000000, 104.000000) rotate(-180.000000) translate(-104.000000, -104.000000) translate(80.000000, 80.000000)\">\n <path d=\"M5.29777586e-31,8 C1.59060409e-15,3.581722 3.581722,0 8,0 L40,0 C44.418278,0 48,3.581722 48,8 C48,12.418278 44.418278,16 40,16 L16,16 L16,40 C16,44.418278 12.418278,48 8,48 C3.581722,48 -3.55271368e-15,44.418278 0,40 L3.55271368e-15,8 Z\"></path>\n </g>\n <g transform=\"translate(24.000000, 104.000000) rotate(-90.000000) translate(-24.000000, -104.000000) translate(0.000000, 80.000000)\">\n <path d=\"M5.29777586e-31,8 C1.59060409e-15,3.581722 3.581722,0 8,0 L40,0 C44.418278,0 48,3.581722 48,8 C48,12.418278 44.418278,16 40,16 L16,16 L16,40 C16,44.418278 12.418278,48 8,48 C3.581722,48 -3.55271368e-15,44.418278 0,40 L3.55271368e-15,8 Z\"></path>\n </g>\n <g transform=\"translate(104.000000, 24.000000) rotate(90.000000) translate(-104.000000, -24.000000) translate(80.000000, 0.000000)\">\n <path d=\"M5.29777586e-31,8 C1.59060409e-15,3.581722 3.581722,0 8,0 L40,0 C44.418278,0 48,3.581722 48,8 C48,12.418278 44.418278,16 40,16 L16,16 L16,40 C16,44.418278 12.418278,48 8,48 C3.581722,48 -3.55271368e-15,44.418278 0,40 L3.55271368e-15,8 Z\"></path>\n </g>\n </g>\n</svg>"
},
"$:/core/images/github": {
"title": "$:/core/images/github",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-github tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M63.9383506,1.60695328 C28.6017227,1.60695328 -0.055756057,30.2970814 -0.055756057,65.6906208 C-0.055756057,94.003092 18.2804728,118.019715 43.7123154,126.493393 C46.9143781,127.083482 48.0812647,125.104717 48.0812647,123.405261 C48.0812647,121.886765 48.02626,117.85449 47.9948287,112.508284 C30.1929317,116.379268 26.4368926,103.916587 26.4368926,103.916587 C23.5255693,96.5129372 19.3294921,94.5420399 19.3294921,94.5420399 C13.5186324,90.5687739 19.7695302,90.6474524 19.7695302,90.6474524 C26.1933001,91.099854 29.5721638,97.2525155 29.5721638,97.2525155 C35.2808718,107.044059 44.5531024,104.215566 48.1991321,102.575118 C48.7806109,98.4366275 50.4346826,95.612068 52.2616263,94.0109598 C38.0507543,92.3941159 23.1091047,86.8944862 23.1091047,62.3389152 C23.1091047,55.3443933 25.6039634,49.6205298 29.6978889,45.1437211 C29.0378318,43.5229433 26.8415704,37.0044266 30.3265147,28.1845627 C30.3265147,28.1845627 35.6973364,26.4615028 47.9241083,34.7542205 C53.027764,33.330139 58.5046663,32.6220321 63.9462084,32.5944947 C69.3838216,32.6220321 74.856795,33.330139 79.9683085,34.7542205 C92.1872225,26.4615028 97.5501864,28.1845627 97.5501864,28.1845627 C101.042989,37.0044266 98.8467271,43.5229433 98.190599,45.1437211 C102.292382,49.6205298 104.767596,55.3443933 104.767596,62.3389152 C104.767596,86.9574291 89.8023734,92.3744463 75.5482834,93.9598188 C77.8427675,95.9385839 79.8897303,99.8489072 79.8897303,105.828476 C79.8897303,114.392635 79.8111521,121.304544 79.8111521,123.405261 C79.8111521,125.120453 80.966252,127.114954 84.2115327,126.489459 C109.623731,117.996111 127.944244,93.9952241 127.944244,65.6906208 C127.944244,30.2970814 99.2867652,1.60695328 63.9383506,1.60695328\"></path>\n </g>\n </svg>\n"
},
"$:/core/images/gitter": {
"title": "$:/core/images/gitter",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-gitter tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 18 25\">\n <rect x=\"15\" y=\"5\" width=\"2\" height=\"10\"></rect>\n <rect x=\"10\" y=\"5\" width=\"2\" height=\"20\"></rect>\n <rect x=\"5\" y=\"5\" width=\"2\" height=\"20\"></rect>\n <rect width=\"2\" height=\"15\"></rect>\n</svg>\n"
},
"$:/core/images/globe": {
"title": "$:/core/images/globe",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-globe tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M72.8111354,37.1275855 C72.8111354,37.9789875 72.8111354,38.8303894 72.8111354,39.6817913 C72.8111354,41.8784743 73.7885604,46.5631866 72.8111354,48.5143758 C71.3445471,51.4420595 68.1617327,52.0543531 66.4170946,54.3812641 C65.2352215,55.9575873 61.7987417,64.9821523 62.7262858,67.3005778 C66.6959269,77.2228204 74.26087,70.4881886 80.6887657,76.594328 C81.5527211,77.415037 83.5758191,78.8666631 83.985137,79.8899578 C87.2742852,88.1128283 76.4086873,94.8989524 87.7419325,106.189751 C88.9872885,107.430443 91.555495,102.372895 91.8205061,101.575869 C92.6726866,99.0129203 98.5458765,96.1267309 100.908882,94.5234439 C102.928056,93.1534443 105.782168,91.8557166 107.236936,89.7775886 C109.507391,86.5342557 108.717505,82.2640435 110.334606,79.0328716 C112.473794,74.7585014 114.163418,69.3979002 116.332726,65.0674086 C120.230862,57.2857361 121.054075,67.1596684 121.400359,67.5059523 C121.757734,67.8633269 122.411167,67.5059523 122.916571,67.5059523 C123.011132,67.5059523 124.364019,67.6048489 124.432783,67.5059523 C125.0832,66.5705216 123.390209,49.5852316 123.114531,48.2089091 C121.710578,41.1996597 116.17083,32.4278331 111.249523,27.7092761 C104.975994,21.6942076 104.160516,11.5121686 92.9912146,12.7547535 C92.7872931,12.7774397 87.906794,22.9027026 85.2136766,26.2672064 C81.486311,30.9237934 82.7434931,22.1144904 78.6876623,22.1144904 C78.6065806,22.1144904 77.5045497,22.0107615 77.4353971,22.1144904 C76.8488637,22.9942905 75.9952305,26.0101404 75.1288269,26.5311533 C74.8635477,26.6906793 73.4071369,26.2924966 73.2826811,26.5311533 C71.0401728,30.8313939 81.5394677,28.7427264 79.075427,34.482926 C76.7225098,39.9642538 72.747373,32.4860199 72.747373,43.0434079\"></path>\n <path d=\"M44.4668556,7.01044608 C54.151517,13.1403033 45.1489715,19.2084878 47.1611905,23.2253896 C48.8157833,26.5283781 51.4021933,28.6198851 48.8753629,33.038878 C46.8123257,36.6467763 42.0052989,37.0050492 39.251679,39.7621111 C36.2115749,42.8060154 33.7884281,48.7028116 32.4624592,52.6732691 C30.8452419,57.5158356 47.0088721,59.5388126 44.5246867,63.6811917 C43.1386839,65.9923513 37.7785192,65.1466282 36.0880227,63.8791519 C34.9234453,63.0059918 32.4946425,63.3331166 31.6713597,62.0997342 C29.0575851,58.1839669 29.4107339,54.0758543 28.0457962,49.9707786 C27.1076833,47.1493864 21.732611,47.8501656 20.2022714,49.3776393 C19.6790362,49.8998948 19.8723378,51.1703278 19.8723378,51.8829111 C19.8723378,57.1682405 26.9914913,55.1986414 26.9914913,58.3421973 C26.9914913,72.9792302 30.9191897,64.8771867 38.1313873,69.6793121 C48.1678018,76.3618966 45.9763926,76.981595 53.0777543,84.0829567 C56.7511941,87.7563965 60.8192437,87.7689005 62.503478,93.3767069 C64.1046972,98.7081071 53.1759798,98.7157031 50.786754,100.825053 C49.663965,101.816317 47.9736094,104.970571 46.5680513,105.439676 C44.7757187,106.037867 43.334221,105.93607 41.6242359,107.219093 C39.1967302,109.040481 37.7241465,112.151588 37.6034934,112.030935 C35.4555278,109.88297 34.0848666,96.5511248 33.7147244,93.7726273 C33.1258872,89.3524817 28.1241923,88.2337027 26.7275443,84.7420826 C25.1572737,80.8164061 28.2518481,75.223612 25.599097,70.9819941 C19.0797019,60.557804 13.7775712,56.4811506 10.2493953,44.6896152 C9.3074899,41.5416683 13.5912267,38.1609942 15.1264825,35.8570308 C17.0029359,33.0410312 17.7876232,30.0028946 19.8723378,27.2224065 C22.146793,24.1888519 40.8551166,9.46076832 43.8574051,8.63490613 L44.4668556,7.01044608 Z\"></path>\n <path d=\"M64,126 C98.2416545,126 126,98.2416545 126,64 C126,29.7583455 98.2416545,2 64,2 C29.7583455,2 2,29.7583455 2,64 C2,98.2416545 29.7583455,126 64,126 Z M64,120 C94.927946,120 120,94.927946 120,64 C120,33.072054 94.927946,8 64,8 C33.072054,8 8,33.072054 8,64 C8,94.927946 33.072054,120 64,120 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/heading-1": {
"title": "$:/core/images/heading-1",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-heading-1 tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M14,30 L27.25,30 L27.25,60.104 L61.7,60.104 L61.7,30 L74.95,30 L74.95,105.684 L61.7,105.684 L61.7,71.552 L27.25,71.552 L27.25,105.684 L14,105.684 L14,30 Z M84.3350766,43.78 C86.8790893,43.78 89.3523979,43.5680021 91.7550766,43.144 C94.1577553,42.7199979 96.3307336,42.0133383 98.2740766,41.024 C100.21742,40.0346617 101.87807,38.7626744 103.256077,37.208 C104.634084,35.6533256 105.535075,33.7453446 105.959077,31.484 L115.817077,31.484 L115.817077,105.684 L102.567077,105.684 L102.567077,53.32 L84.3350766,53.32 L84.3350766,43.78 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/heading-2": {
"title": "$:/core/images/heading-2",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-heading-2 tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M6,30 L19.25,30 L19.25,60.104 L53.7,60.104 L53.7,30 L66.95,30 L66.95,105.684 L53.7,105.684 L53.7,71.552 L19.25,71.552 L19.25,105.684 L6,105.684 L6,30 Z M125.519077,105.684 L74.8510766,105.684 C74.9217436,99.5359693 76.4057288,94.1653563 79.3030766,89.572 C82.2004244,84.9786437 86.1577182,80.986017 91.1750766,77.594 C93.5777553,75.8273245 96.0863969,74.113675 98.7010766,72.453 C101.315756,70.792325 103.718399,69.0080095 105.909077,67.1 C108.099754,65.1919905 109.901736,63.1250111 111.315077,60.899 C112.728417,58.6729889 113.47041,56.1113478 113.541077,53.214 C113.541077,51.8713266 113.382078,50.4403409 113.064077,48.921 C112.746075,47.4016591 112.127748,45.9883399 111.209077,44.681 C110.290405,43.3736601 109.018418,42.2783377 107.393077,41.395 C105.767735,40.5116622 103.647756,40.07 101.033077,40.07 C98.6303979,40.07 96.6340846,40.5469952 95.0440766,41.501 C93.4540687,42.4550048 92.1820814,43.762325 91.2280766,45.423 C90.2740719,47.083675 89.5674123,49.0446554 89.1080766,51.306 C88.648741,53.5673446 88.3837436,56.0053203 88.3130766,58.62 L76.2290766,58.62 C76.2290766,54.5213128 76.7767378,50.7230175 77.8720766,47.225 C78.9674154,43.7269825 80.610399,40.7060127 82.8010766,38.162 C84.9917542,35.6179873 87.6593942,33.6216739 90.8040766,32.173 C93.948759,30.7243261 97.6057224,30 101.775077,30 C106.297766,30 110.078395,30.7419926 113.117077,32.226 C116.155758,33.7100074 118.611401,35.5826554 120.484077,37.844 C122.356753,40.1053446 123.681739,42.5609868 124.459077,45.211 C125.236414,47.8610133 125.625077,50.3873213 125.625077,52.79 C125.625077,55.7580148 125.165748,58.4433213 124.247077,60.846 C123.328405,63.2486787 122.091751,65.4569899 120.537077,67.471 C118.982402,69.4850101 117.215753,71.3399915 115.237077,73.036 C113.2584,74.7320085 111.209087,76.3219926 109.089077,77.806 C106.969066,79.2900074 104.849087,80.7033266 102.729077,82.046 C100.609066,83.3886734 98.6480856,84.7313266 96.8460766,86.074 C95.0440676,87.4166734 93.47175,88.8123261 92.1290766,90.261 C90.7864032,91.7096739 89.8677458,93.2466585 89.3730766,94.872 L125.519077,94.872 L125.519077,105.684 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/heading-3": {
"title": "$:/core/images/heading-3",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-heading-3 tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M6,30 L19.25,30 L19.25,60.104 L53.7,60.104 L53.7,30 L66.95,30 L66.95,105.684 L53.7,105.684 L53.7,71.552 L19.25,71.552 L19.25,105.684 L6,105.684 L6,30 Z M94.8850766,62.224 C96.8637532,62.294667 98.8424001,62.1533351 100.821077,61.8 C102.799753,61.4466649 104.566402,60.8283378 106.121077,59.945 C107.675751,59.0616623 108.930072,57.8426744 109.884077,56.288 C110.838081,54.7333256 111.315077,52.8253446 111.315077,50.564 C111.315077,47.3839841 110.237421,44.8400095 108.082077,42.932 C105.926733,41.0239905 103.153094,40.07 99.7610766,40.07 C97.641066,40.07 95.8037511,40.4939958 94.2490766,41.342 C92.6944022,42.1900042 91.4047484,43.3383261 90.3800766,44.787 C89.3554048,46.2356739 88.5957458,47.860991 88.1010766,49.663 C87.6064075,51.465009 87.3944096,53.3199905 87.4650766,55.228 L75.3810766,55.228 C75.5224107,51.623982 76.1937373,48.2850154 77.3950766,45.211 C78.596416,42.1369846 80.2393995,39.4693446 82.3240766,37.208 C84.4087537,34.9466554 86.9350618,33.1800064 89.9030766,31.908 C92.8710915,30.6359936 96.2277246,30 99.9730766,30 C102.870424,30 105.714729,30.4239958 108.506077,31.272 C111.297424,32.1200042 113.806065,33.3566585 116.032077,34.982 C118.258088,36.6073415 120.042403,38.6743208 121.385077,41.183 C122.72775,43.6916792 123.399077,46.5713171 123.399077,49.822 C123.399077,53.5673521 122.551085,56.8356527 120.855077,59.627 C119.159068,62.4183473 116.509095,64.4499936 112.905077,65.722 L112.905077,65.934 C117.145098,66.7820042 120.448731,68.8843166 122.816077,72.241 C125.183422,75.5976835 126.367077,79.6786426 126.367077,84.484 C126.367077,88.017351 125.660417,91.1796527 124.247077,93.971 C122.833736,96.7623473 120.925755,99.129657 118.523077,101.073 C116.120398,103.016343 113.329093,104.517995 110.149077,105.578 C106.969061,106.638005 103.612428,107.168 100.079077,107.168 C95.7683884,107.168 92.005426,106.549673 88.7900766,105.313 C85.5747272,104.076327 82.8894207,102.327345 80.7340766,100.066 C78.5787325,97.8046554 76.9357489,95.0840159 75.8050766,91.904 C74.6744043,88.7239841 74.0737436,85.1906861 74.0030766,81.304 L86.0870766,81.304 C85.9457426,85.8266893 87.0587315,89.5896517 89.4260766,92.593 C91.7934218,95.5963483 95.3443863,97.098 100.079077,97.098 C104.107097,97.098 107.481396,95.9496782 110.202077,93.653 C112.922757,91.3563219 114.283077,88.0880212 114.283077,83.848 C114.283077,80.9506522 113.717749,78.6540085 112.587077,76.958 C111.456404,75.2619915 109.972419,73.9723378 108.135077,73.089 C106.297734,72.2056623 104.230755,71.6580011 101.934077,71.446 C99.6373985,71.2339989 97.2877553,71.163333 94.8850766,71.234 L94.8850766,62.224 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/heading-4": {
"title": "$:/core/images/heading-4",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-heading-4 tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M8,30 L21.25,30 L21.25,60.104 L55.7,60.104 L55.7,30 L68.95,30 L68.95,105.684 L55.7,105.684 L55.7,71.552 L21.25,71.552 L21.25,105.684 L8,105.684 L8,30 Z M84.5890766,78.548 L107.061077,78.548 L107.061077,45.9 L106.849077,45.9 L84.5890766,78.548 Z M128.049077,88.088 L118.509077,88.088 L118.509077,105.684 L107.061077,105.684 L107.061077,88.088 L75.2610766,88.088 L75.2610766,76.11 L107.061077,31.484 L118.509077,31.484 L118.509077,78.548 L128.049077,78.548 L128.049077,88.088 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/heading-5": {
"title": "$:/core/images/heading-5",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-heading-5 tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M6,30 L19.25,30 L19.25,60.104 L53.7,60.104 L53.7,30 L66.95,30 L66.95,105.684 L53.7,105.684 L53.7,71.552 L19.25,71.552 L19.25,105.684 L6,105.684 L6,30 Z M83.7550766,31.484 L122.127077,31.484 L122.127077,42.296 L92.7650766,42.296 L88.9490766,61.164 L89.1610766,61.376 C90.7864181,59.5386575 92.8533974,58.1430048 95.3620766,57.189 C97.8707558,56.2349952 100.361731,55.758 102.835077,55.758 C106.509762,55.758 109.795729,56.3763272 112.693077,57.613 C115.590424,58.8496729 118.0284,60.5809889 120.007077,62.807 C121.985753,65.0330111 123.487405,67.6653181 124.512077,70.704 C125.536748,73.7426819 126.049077,77.028649 126.049077,80.562 C126.049077,83.5300148 125.572081,86.5863176 124.618077,89.731 C123.664072,92.8756824 122.144754,95.7376538 120.060077,98.317 C117.9754,100.896346 115.30776,103.016325 112.057077,104.677 C108.806394,106.337675 104.919766,107.168 100.397077,107.168 C96.7930586,107.168 93.454092,106.691005 90.3800766,105.737 C87.3060613,104.782995 84.6030883,103.35201 82.2710766,101.444 C79.939065,99.5359905 78.0840835,97.1863473 76.7060766,94.395 C75.3280697,91.6036527 74.5684107,88.3353521 74.4270766,84.59 L86.5110766,84.59 C86.8644117,88.6180201 88.2423979,91.7096559 90.6450766,93.865 C93.0477553,96.0203441 96.2277235,97.098 100.185077,97.098 C102.729089,97.098 104.884401,96.6740042 106.651077,95.826 C108.417752,94.9779958 109.848738,93.8120074 110.944077,92.328 C112.039415,90.8439926 112.816741,89.1126766 113.276077,87.134 C113.735412,85.1553234 113.965077,83.0353446 113.965077,80.774 C113.965077,78.7246564 113.682413,76.763676 113.117077,74.891 C112.55174,73.018324 111.703749,71.3753404 110.573077,69.962 C109.442404,68.5486596 107.976086,67.4180042 106.174077,66.57 C104.372068,65.7219958 102.269755,65.298 99.8670766,65.298 C97.3230639,65.298 94.9380878,65.7749952 92.7120766,66.729 C90.4860655,67.6830048 88.8784149,69.4673203 87.8890766,72.082 L75.8050766,72.082 L83.7550766,31.484 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/heading-6": {
"title": "$:/core/images/heading-6",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-heading-6 tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M6,30 L19.25,30 L19.25,60.104 L53.7,60.104 L53.7,30 L66.95,30 L66.95,105.684 L53.7,105.684 L53.7,71.552 L19.25,71.552 L19.25,105.684 L6,105.684 L6,30 Z M112.587077,50.246 C112.304409,47.2073181 111.226753,44.751676 109.354077,42.879 C107.481401,41.006324 104.955093,40.07 101.775077,40.07 C99.584399,40.07 97.6940846,40.4763293 96.1040766,41.289 C94.5140687,42.1016707 93.1714154,43.1793266 92.0760766,44.522 C90.9807378,45.8646734 90.0974133,47.401658 89.4260766,49.133 C88.7547399,50.864342 88.2070787,52.6839905 87.7830766,54.592 C87.3590745,56.5000095 87.0587442,58.390324 86.8820766,60.263 C86.7054091,62.135676 86.5464107,63.8846585 86.4050766,65.51 L86.6170766,65.722 C88.2424181,62.7539852 90.4860623,60.5456739 93.3480766,59.097 C96.2100909,57.6483261 99.3017267,56.924 102.623077,56.924 C106.297762,56.924 109.583729,57.5599936 112.481077,58.832 C115.378424,60.1040064 117.834067,61.8529889 119.848077,64.079 C121.862087,66.3050111 123.399071,68.9373181 124.459077,71.976 C125.519082,75.0146819 126.049077,78.300649 126.049077,81.834 C126.049077,85.438018 125.466082,88.7769846 124.300077,91.851 C123.134071,94.9250154 121.455754,97.6103219 119.265077,99.907 C117.074399,102.203678 114.459758,103.987994 111.421077,105.26 C108.382395,106.532006 105.025762,107.168 101.351077,107.168 C95.9097161,107.168 91.4400941,106.16101 87.9420766,104.147 C84.4440591,102.13299 81.6880867,99.3770175 79.6740766,95.879 C77.6600666,92.3809825 76.2644138,88.2823568 75.4870766,83.583 C74.7097394,78.8836432 74.3210766,73.8133605 74.3210766,68.372 C74.3210766,63.9199777 74.7980719,59.4326893 75.7520766,54.91 C76.7060814,50.3873107 78.278399,46.2710186 80.4690766,42.561 C82.6597542,38.8509815 85.5393921,35.8300117 89.1080766,33.498 C92.6767611,31.1659883 97.0757171,30 102.305077,30 C105.273091,30 108.064397,30.4946617 110.679077,31.484 C113.293756,32.4733383 115.608067,33.8513245 117.622077,35.618 C119.636087,37.3846755 121.27907,39.5046543 122.551077,41.978 C123.823083,44.4513457 124.529743,47.2073181 124.671077,50.246 L112.587077,50.246 Z M100.927077,97.098 C103.117754,97.098 105.025735,96.6563378 106.651077,95.773 C108.276418,94.8896623 109.636738,93.7413404 110.732077,92.328 C111.827415,90.9146596 112.640074,89.271676 113.170077,87.399 C113.700079,85.526324 113.965077,83.6006766 113.965077,81.622 C113.965077,79.6433234 113.700079,77.7353425 113.170077,75.898 C112.640074,74.0606575 111.827415,72.4530069 110.732077,71.075 C109.636738,69.6969931 108.276418,68.5840042 106.651077,67.736 C105.025735,66.8879958 103.117754,66.464 100.927077,66.464 C98.736399,66.464 96.8107516,66.8703293 95.1500766,67.683 C93.4894017,68.4956707 92.0937489,69.5909931 90.9630766,70.969 C89.8324043,72.3470069 88.9844128,73.9546575 88.4190766,75.792 C87.8537405,77.6293425 87.5710766,79.5726564 87.5710766,81.622 C87.5710766,83.6713436 87.8537405,85.6146575 88.4190766,87.452 C88.9844128,89.2893425 89.8324043,90.9323261 90.9630766,92.381 C92.0937489,93.8296739 93.4894017,94.9779958 95.1500766,95.826 C96.8107516,96.6740042 98.736399,97.098 100.927077,97.098 L100.927077,97.098 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/help": {
"title": "$:/core/images/help",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-help tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M36.0548906,111.44117 C30.8157418,115.837088 20.8865444,118.803477 9.5,118.803477 C7.86465619,118.803477 6.25937294,118.742289 4.69372699,118.624467 C12.612543,115.984876 18.7559465,110.02454 21.0611049,102.609942 C8.74739781,92.845129 1.04940554,78.9359851 1.04940554,63.5 C1.04940554,33.9527659 29.2554663,10 64.0494055,10 C98.8433448,10 127.049406,33.9527659 127.049406,63.5 C127.049406,93.0472341 98.8433448,117 64.0494055,117 C53.9936953,117 44.48824,114.999337 36.0548906,111.44117 L36.0548906,111.44117 Z M71.4042554,77.5980086 C71.406883,77.2865764 71.4095079,76.9382011 71.4119569,76.5610548 C71.4199751,75.3262169 71.4242825,74.0811293 71.422912,72.9158546 C71.4215244,71.736154 71.4143321,70.709635 71.4001396,69.8743525 C71.4078362,68.5173028 71.9951951,67.7870427 75.1273009,65.6385471 C75.2388969,65.5619968 76.2124091,64.8981068 76.5126553,64.6910879 C79.6062455,62.5580654 81.5345849,60.9050204 83.2750652,58.5038955 C85.6146327,55.2762841 86.8327108,51.426982 86.8327108,46.8554323 C86.8327108,33.5625756 76.972994,24.9029551 65.3778484,24.9029551 C54.2752771,24.9029551 42.8794554,34.5115163 41.3121702,47.1975534 C40.9043016,50.4989536 43.2499725,53.50591 46.5513726,53.9137786 C49.8527728,54.3216471 52.8597292,51.9759763 53.2675978,48.6745761 C54.0739246,42.1479456 60.2395837,36.9492759 65.3778484,36.9492759 C70.6427674,36.9492759 74.78639,40.5885487 74.78639,46.8554323 C74.78639,50.4892974 73.6853224,52.008304 69.6746221,54.7736715 C69.4052605,54.9593956 68.448509,55.6118556 68.3131127,55.7047319 C65.6309785,57.5445655 64.0858213,58.803255 62.6123358,60.6352315 C60.5044618,63.2559399 59.3714208,66.3518252 59.3547527,69.9487679 C59.3684999,70.8407274 59.3752803,71.8084521 59.3765995,72.9300232 C59.3779294,74.0607297 59.3737237,75.2764258 59.36589,76.482835 C59.3634936,76.8518793 59.3609272,77.1924914 59.3583633,77.4963784 C59.3568319,77.6778944 59.3556368,77.8074256 59.3549845,77.8730928 C59.3219814,81.1994287 61.9917551,83.9227111 65.318091,83.9557142 C68.644427,83.9887173 71.3677093,81.3189435 71.4007124,77.9926076 C71.4014444,77.9187458 71.402672,77.7856841 71.4042554,77.5980086 Z M65.3778489,102.097045 C69.5359735,102.097045 72.9067994,98.7262189 72.9067994,94.5680944 C72.9067994,90.4099698 69.5359735,87.0391439 65.3778489,87.0391439 C61.2197243,87.0391439 57.8488984,90.4099698 57.8488984,94.5680944 C57.8488984,98.7262189 61.2197243,102.097045 65.3778489,102.097045 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/home-button": {
"title": "$:/core/images/home-button",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-home-button tc-image-button\" viewBox=\"0 0 128 128\" width=\"22pt\" height=\"22pt\">\n <g fill-rule=\"evenodd\">\n <path d=\"M112.9847,119.501583 C112.99485,119.336814 113,119.170705 113,119.003406 L113,67.56802 C116.137461,70.5156358 121.076014,70.4518569 124.133985,67.3938855 C127.25818,64.2696912 127.260618,59.2068102 124.131541,56.0777326 L70.3963143,2.34250601 C68.8331348,0.779326498 66.7828947,-0.000743167069 64.7337457,1.61675364e-05 C62.691312,-0.00409949529 60.6426632,0.777559815 59.077717,2.34250601 L33,28.420223 L33,28.420223 L33,8.00697327 C33,3.58484404 29.4092877,0 25,0 C20.581722,0 17,3.59075293 17,8.00697327 L17,44.420223 L5.3424904,56.0777326 C2.21694607,59.2032769 2.22220878,64.2760483 5.34004601,67.3938855 C8.46424034,70.5180798 13.5271213,70.5205187 16.6561989,67.3914411 L17,67.04764 L17,119.993027 C17,119.994189 17.0000002,119.995351 17.0000007,119.996514 C17.0000002,119.997675 17,119.998838 17,120 C17,124.418278 20.5881049,128 24.9992458,128 L105.000754,128 C109.418616,128 113,124.409288 113,120 C113,119.832611 112.99485,119.666422 112.9847,119.501583 Z M97,112 L97,51.5736087 L97,51.5736087 L64.7370156,19.3106244 L33,51.04764 L33,112 L97,112 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/import-button": {
"title": "$:/core/images/import-button",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-import-button tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M105.449437,94.2138951 C105.449437,94.2138951 110.049457,94.1897106 110.049457,99.4026111 C110.049457,104.615512 105.163246,104.615511 105.163246,104.615511 L45.0075072,105.157833 C45.0075072,105.157833 0.367531803,106.289842 0.367532368,66.6449212 C0.367532934,27.0000003 45.0428249,27.0000003 45.0428249,27.0000003 L105.532495,27.0000003 C105.532495,27.0000003 138.996741,25.6734987 138.996741,55.1771866 C138.996741,84.6808745 105.727102,82.8457535 105.727102,82.8457535 L56.1735087,82.8457535 C56.1735087,82.8457535 22.6899229,85.1500223 22.6899229,66.0913753 C22.6899229,47.0327282 56.1735087,49.3383013 56.1735087,49.3383013 L105.727102,49.3383013 C105.727102,49.3383013 111.245209,49.3383024 111.245209,54.8231115 C111.245209,60.3079206 105.727102,60.5074524 105.727102,60.5074524 L56.1735087,60.5074524 C56.1735087,60.5074524 37.48913,60.5074528 37.48913,66.6449195 C37.48913,72.7823862 56.1735087,71.6766023 56.1735087,71.6766023 L105.727102,71.6766029 C105.727102,71.6766029 127.835546,73.1411469 127.835546,55.1771866 C127.835546,35.5304025 105.727102,38.3035317 105.727102,38.3035317 L45.0428249,38.3035317 C45.0428249,38.3035317 11.5287276,38.3035313 11.5287276,66.6449208 C11.5287276,94.9863103 45.0428244,93.9579678 45.0428244,93.9579678 L105.449437,94.2138951 Z\" transform=\"translate(69.367532, 66.000000) rotate(-45.000000) translate(-69.367532, -66.000000) \"></path>\n </g>\n</svg>"
},
"$:/core/images/info-button": {
"title": "$:/core/images/info-button",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-info-button tc-image-button\" viewBox=\"0 0 128 128\" width=\"22pt\" height=\"22pt\">\n <g fill-rule=\"evenodd\">\n <g transform=\"translate(0.049406, 0.000000)\">\n <path d=\"M64,128 C99.346224,128 128,99.346224 128,64 C128,28.653776 99.346224,0 64,0 C28.653776,0 0,28.653776 0,64 C0,99.346224 28.653776,128 64,128 Z M64,112 C90.509668,112 112,90.509668 112,64 C112,37.490332 90.509668,16 64,16 C37.490332,16 16,37.490332 16,64 C16,90.509668 37.490332,112 64,112 Z\"></path>\n <circle cx=\"64\" cy=\"32\" r=\"8\"></circle>\n <rect x=\"56\" y=\"48\" width=\"16\" height=\"56\" rx=\"8\"></rect>\n </g>\n </g>\n</svg>"
},
"$:/core/images/italic": {
"title": "$:/core/images/italic",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-italic tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <polygon points=\"66.7114846 0 89.1204482 0 62.4089636 128 40 128\"></polygon>\n </g>\n</svg>"
},
"$:/core/images/left-arrow": {
"title": "$:/core/images/left-arrow",
"created": "20150315234410875",
"modified": "20150315235324760",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-left-arrow tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <path transform=\"rotate(135, 63.8945, 64.1752)\" d=\"m109.07576,109.35336c-1.43248,1.43361 -3.41136,2.32182 -5.59717,2.32182l-79.16816,0c-4.36519,0 -7.91592,-3.5444 -7.91592,-7.91666c0,-4.36337 3.54408,-7.91667 7.91592,-7.91667l71.25075,0l0,-71.25075c0,-4.3652 3.54442,-7.91592 7.91667,-7.91592c4.36336,0 7.91667,3.54408 7.91667,7.91592l0,79.16815c0,2.1825 -0.88602,4.16136 -2.3185,5.59467l-0.00027,-0.00056z\"/>\n</svg>\n"
},
"$:/core/images/line-width": {
"title": "$:/core/images/line-width",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-line-width tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M128,-97 L112.992786,-97 C112.452362,-97 112,-96.5522847 112,-96 C112,-95.4438648 112.444486,-95 112.992786,-95 L128,-95 L128,-97 Z M128,-78.6794919 L111.216185,-88.3696322 C110.748163,-88.6398444 110.132549,-88.4782926 109.856406,-88 C109.578339,-87.5183728 109.741342,-86.9117318 110.216185,-86.6375814 L128,-76.3700908 L128,-78.6794919 Z M78.6794919,-128 L88.3696322,-111.216185 C88.6437826,-110.741342 88.4816272,-110.134474 88,-109.856406 C87.5217074,-109.580264 86.9077936,-109.748163 86.6375814,-110.216185 L76.3700908,-128 L78.6794919,-128 Z M97,-128 L97,-112.992786 C97,-112.444486 96.5561352,-112 96,-112 C95.4477153,-112 95,-112.452362 95,-112.992786 L95,-128 L97,-128 Z M115.629909,-128 L105.362419,-110.216185 C105.088268,-109.741342 104.481627,-109.578339 104,-109.856406 C103.521707,-110.132549 103.360156,-110.748163 103.630368,-111.216185 L113.320508,-128 L115.629909,-128 Z M128,-113.320508 L111.216185,-103.630368 C110.741342,-103.356217 110.134474,-103.518373 109.856406,-104 C109.580264,-104.478293 109.748163,-105.092206 110.216185,-105.362419 L128,-115.629909 L128,-113.320508 Z M48,-96 C48,-96.5522847 48.4523621,-97 48.9927864,-97 L79.0072136,-97 C79.5555144,-97 80,-96.5561352 80,-96 C80,-95.4477153 79.5476379,-95 79.0072136,-95 L48.9927864,-95 C48.4444856,-95 48,-95.4438648 48,-96 Z M54.4307806,-120 C54.706923,-120.478293 55.3225377,-120.639844 55.7905589,-120.369632 L81.7838153,-105.362419 C82.2586577,-105.088268 82.4216611,-104.481627 82.1435935,-104 C81.8674512,-103.521707 81.2518365,-103.360156 80.7838153,-103.630368 L54.7905589,-118.637581 C54.3157165,-118.911732 54.152713,-119.518373 54.4307806,-120 Z M104,-82.1435935 C104.478293,-82.4197359 105.092206,-82.2518365 105.362419,-81.7838153 L120.369632,-55.7905589 C120.643783,-55.3157165 120.481627,-54.7088482 120,-54.4307806 C119.521707,-54.1546382 118.907794,-54.3225377 118.637581,-54.7905589 L103.630368,-80.7838153 C103.356217,-81.2586577 103.518373,-81.865526 104,-82.1435935 Z M96,-80 C96.5522847,-80 97,-79.5476379 97,-79.0072136 L97,-48.9927864 C97,-48.4444856 96.5561352,-48 96,-48 C95.4477153,-48 95,-48.4523621 95,-48.9927864 L95,-79.0072136 C95,-79.5555144 95.4438648,-80 96,-80 Z M88,-82.1435935 C88.4782926,-81.8674512 88.6398444,-81.2518365 88.3696322,-80.7838153 L73.3624186,-54.7905589 C73.0882682,-54.3157165 72.4816272,-54.152713 72,-54.4307806 C71.5217074,-54.706923 71.3601556,-55.3225377 71.6303678,-55.7905589 L86.6375814,-81.7838153 C86.9117318,-82.2586577 87.5183728,-82.4216611 88,-82.1435935 Z M82.1435935,-88 C82.4197359,-87.5217074 82.2518365,-86.9077936 81.7838153,-86.6375814 L55.7905589,-71.6303678 C55.3157165,-71.3562174 54.7088482,-71.5183728 54.4307806,-72 C54.1546382,-72.4782926 54.3225377,-73.0922064 54.7905589,-73.3624186 L80.7838153,-88.3696322 C81.2586577,-88.6437826 81.865526,-88.4816272 82.1435935,-88 Z M1.30626177e-08,-41.9868843 L15.0170091,-57.9923909 L20.7983821,-52.9749272 L44.7207091,-81.2095939 L73.4260467,-42.1002685 L85.984793,-56.6159488 L104.48741,-34.0310661 L127.969109,-47.4978019 L127.969109,7.99473128e-07 L1.30626177e-08,7.99473128e-07 L1.30626177e-08,-41.9868843 Z M96,-84 C102.627417,-84 108,-89.372583 108,-96 C108,-102.627417 102.627417,-108 96,-108 C89.372583,-108 84,-102.627417 84,-96 C84,-89.372583 89.372583,-84 96,-84 Z\"></path>\n <path d=\"M16,18 L112,18 C113.104569,18 114,17.1045695 114,16 C114,14.8954305 113.104569,14 112,14 L16,14 C14.8954305,14 14,14.8954305 14,16 C14,17.1045695 14.8954305,18 16,18 L16,18 Z M16,35 L112,35 C114.209139,35 116,33.209139 116,31 C116,28.790861 114.209139,27 112,27 L16,27 C13.790861,27 12,28.790861 12,31 C12,33.209139 13.790861,35 16,35 L16,35 Z M16,56 L112,56 C115.313708,56 118,53.3137085 118,50 C118,46.6862915 115.313708,44 112,44 L16,44 C12.6862915,44 10,46.6862915 10,50 C10,53.3137085 12.6862915,56 16,56 L16,56 Z M16,85 L112,85 C117.522847,85 122,80.5228475 122,75 C122,69.4771525 117.522847,65 112,65 L16,65 C10.4771525,65 6,69.4771525 6,75 C6,80.5228475 10.4771525,85 16,85 L16,85 Z M16,128 L112,128 C120.836556,128 128,120.836556 128,112 C128,103.163444 120.836556,96 112,96 L16,96 C7.163444,96 0,103.163444 0,112 C0,120.836556 7.163444,128 16,128 L16,128 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/link": {
"title": "$:/core/images/link",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-link tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M128.719999,57.568543 C130.219553,53.8628171 131.045202,49.8121445 131.045202,45.5685425 C131.045202,27.8915447 116.718329,13.5685425 99.0452364,13.5685425 L67.0451674,13.5685425 C49.3655063,13.5685425 35.0452019,27.8954305 35.0452019,45.5685425 C35.0452019,63.2455403 49.3720745,77.5685425 67.0451674,77.5685425 L99.0452364,77.5685425 C100.406772,77.5685425 101.748384,77.4835732 103.065066,77.3186499 C96.4792444,73.7895096 91.1190212,68.272192 87.7873041,61.5685425 L67.0506214,61.5685425 C58.2110723,61.5685425 51.0452019,54.4070414 51.0452019,45.5685425 C51.0452019,36.7319865 58.2005234,29.5685425 67.0506214,29.5685425 L99.0397824,29.5685425 C107.879331,29.5685425 115.045202,36.7300436 115.045202,45.5685425 C115.045202,48.9465282 113.99957,52.0800164 112.21335,54.6623005 C114.314383,56.4735917 117.050039,57.5685425 120.041423,57.5685425 L128.720003,57.5685425 Z\" transform=\"translate(83.045202, 45.568542) rotate(-225.000000) translate(-83.045202, -45.568542)\"></path>\n <path d=\"M-0.106255113,71.0452019 C-1.60580855,74.7509276 -2.43145751,78.8016001 -2.43145751,83.0452019 C-2.43145751,100.7222 11.8954151,115.045202 29.568508,115.045202 L61.568577,115.045202 C79.2482381,115.045202 93.5685425,100.718314 93.5685425,83.0452019 C93.5685425,65.3682041 79.2416699,51.0452019 61.568577,51.0452019 L29.568508,51.0452019 C28.206973,51.0452019 26.8653616,51.1301711 25.5486799,51.2950943 C32.1345,54.8242347 37.4947231,60.3415524 40.8264403,67.0452019 L61.563123,67.0452019 C70.4026721,67.0452019 77.5685425,74.206703 77.5685425,83.0452019 C77.5685425,91.8817579 70.413221,99.0452019 61.563123,99.0452019 L29.573962,99.0452019 C20.7344129,99.0452019 13.5685425,91.8837008 13.5685425,83.0452019 C13.5685425,79.6672162 14.6141741,76.533728 16.4003949,73.9514439 C14.2993609,72.1401527 11.5637054,71.0452019 8.5723215,71.0452019 L-0.106255113,71.0452019 Z\" transform=\"translate(45.568542, 83.045202) rotate(-225.000000) translate(-45.568542, -83.045202)\"></path>\n </g>\n</svg>"
},
"$:/core/images/linkify": {
"title": "$:/core/images/linkify",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-linkify-button tc-image-button\" viewBox=\"0 0 128 128\" width=\"22pt\" height=\"22pt\"><path d=\"M17.031 31.919H9.048V96.85h7.983v6.92H0V25h17.031v6.919zm24.66 0h-7.983V96.85h7.983v6.92H24.66V25h17.03v6.919zM67.77 56.422l11.975-3.903 2.306 7.096-12.063 3.903 7.628 10.379-6.12 4.435-7.63-10.467-7.45 10.2-5.943-4.523L58.1 63.518 45.95 59.35l2.306-7.096 12.064 4.17V43.825h7.45v12.596zM86.31 96.85h7.982V31.92H86.31V25h17.031v78.77H86.31v-6.92zm24.659 0h7.983V31.92h-7.983V25H128v78.77h-17.031v-6.92z\" fill-rule=\"evenodd\"/></svg>"
},
"$:/core/images/list-bullet": {
"title": "$:/core/images/list-bullet",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-list-bullet tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M11.6363636,40.2727273 C18.0629498,40.2727273 23.2727273,35.0629498 23.2727273,28.6363636 C23.2727273,22.2097775 18.0629498,17 11.6363636,17 C5.20977746,17 0,22.2097775 0,28.6363636 C0,35.0629498 5.20977746,40.2727273 11.6363636,40.2727273 Z M11.6363636,75.1818182 C18.0629498,75.1818182 23.2727273,69.9720407 23.2727273,63.5454545 C23.2727273,57.1188684 18.0629498,51.9090909 11.6363636,51.9090909 C5.20977746,51.9090909 0,57.1188684 0,63.5454545 C0,69.9720407 5.20977746,75.1818182 11.6363636,75.1818182 Z M11.6363636,110.090909 C18.0629498,110.090909 23.2727273,104.881132 23.2727273,98.4545455 C23.2727273,92.0279593 18.0629498,86.8181818 11.6363636,86.8181818 C5.20977746,86.8181818 0,92.0279593 0,98.4545455 C0,104.881132 5.20977746,110.090909 11.6363636,110.090909 Z M34.9090909,22.8181818 L128,22.8181818 L128,34.4545455 L34.9090909,34.4545455 L34.9090909,22.8181818 Z M34.9090909,57.7272727 L128,57.7272727 L128,69.3636364 L34.9090909,69.3636364 L34.9090909,57.7272727 Z M34.9090909,92.6363636 L128,92.6363636 L128,104.272727 L34.9090909,104.272727 L34.9090909,92.6363636 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/list-number": {
"title": "$:/core/images/list-number",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-list-number tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M33.8390805,22.3563218 L128,22.3563218 L128,34.1264368 L33.8390805,34.1264368 L33.8390805,22.3563218 Z M33.8390805,57.6666667 L128,57.6666667 L128,69.4367816 L33.8390805,69.4367816 L33.8390805,57.6666667 Z M33.8390805,92.9770115 L128,92.9770115 L128,104.747126 L33.8390805,104.747126 L33.8390805,92.9770115 Z M0.379509711,42.6307008 L0.379509711,40.4082314 L1.37821948,40.4082314 C2.20382368,40.4082314 2.82301754,40.268077 3.23581964,39.9877642 C3.64862174,39.7074513 3.85501969,39.0400498 3.85501969,37.9855395 L3.85501969,22.7686318 C3.85501969,21.3270228 3.66193774,20.4327047 3.27576803,20.0856507 C2.88959832,19.7385967 1.79768657,19.5650723 0,19.5650723 L0,17.4226919 C3.50215975,17.2758613 6.25191314,16.4683055 8.24934266,15 L10.3666074,15 L10.3666074,37.865406 C10.3666074,38.786434 10.5164123,39.4404875 10.8160268,39.8275862 C11.1156412,40.2146849 11.764796,40.4082314 12.7635108,40.4082314 L13.7622206,40.4082314 L13.7622206,42.6307008 L0.379509711,42.6307008 Z M0.0798967812,77.9873934 L0.0798967812,76.0852799 C7.27064304,69.5312983 10.8659622,63.5046623 10.8659622,58.005191 C10.8659622,56.4434479 10.5397203,55.195407 9.88722667,54.2610308 C9.23473303,53.3266546 8.36253522,52.8594735 7.27060709,52.8594735 C6.3784219,52.8594735 5.61608107,53.1764892 4.98356173,53.8105302 C4.35104238,54.4445712 4.03478745,55.1753759 4.03478745,56.0029663 C4.03478745,56.9773871 4.28113339,57.8316611 4.77383268,58.5658139 C4.88036225,58.7259926 4.93362624,58.8461249 4.93362624,58.9262143 C4.93362624,59.0730449 4.77383427,59.2065252 4.45424555,59.3266593 C4.2411864,59.4067486 3.70188852,59.6336652 2.83633573,60.0074156 C1.99741533,60.3811661 1.47809145,60.5680386 1.2783485,60.5680386 C1.03865696,60.5680386 0.765679018,60.1976307 0.459406492,59.4568039 C0.153133966,58.715977 0,57.9184322 0,57.0641453 C0,55.1153036 0.848894811,53.5202138 2.5467099,52.2788283 C4.24452499,51.0374428 6.34512352,50.4167594 8.84856852,50.4167594 C11.3120649,50.4167594 13.3793735,51.0874979 15.0505562,52.4289952 C16.7217389,53.7704924 17.5573177,55.5224215 17.5573177,57.684835 C17.5573177,58.9662652 17.2743527,60.2076321 16.7084144,61.4089729 C16.142476,62.6103138 14.7875733,64.4623531 12.6436656,66.9651465 C10.4997579,69.4679398 8.40914641,71.7804862 6.3717683,73.902855 L17.8169822,73.902855 L16.7982982,79.6292176 L14.6810335,79.6292176 C14.7609307,79.3489048 14.8008787,79.0952922 14.8008787,78.8683723 C14.8008787,78.4812736 14.7010087,78.237672 14.5012658,78.1375603 C14.3015228,78.0374485 13.9020429,77.9873934 13.3028141,77.9873934 L0.0798967812,77.9873934 Z M12.2042333,97.1935484 C13.9486551,97.2335931 15.4400468,97.8309175 16.6784531,98.9855395 C17.9168594,100.140162 18.5360532,101.75861 18.5360532,103.840934 C18.5360532,106.830938 17.4041935,109.233584 15.14044,111.048943 C12.8766866,112.864303 10.1402492,113.771969 6.93104577,113.771969 C4.92030005,113.771969 3.26245842,113.388213 1.95747114,112.62069 C0.652483855,111.853166 0,110.848727 0,109.607341 C0,108.833144 0.26964894,108.209124 0.808954909,107.735261 C1.34826088,107.261399 1.93749375,107.024472 2.57667119,107.024472 C3.21584864,107.024472 3.73850152,107.224692 4.14464552,107.625139 C4.55078953,108.025586 4.92696644,108.67964 5.27318756,109.587319 C5.73925445,110.855401 6.51158227,111.489433 7.59019421,111.489433 C8.85523291,111.489433 9.87723568,111.012241 10.6562332,110.057842 C11.4352307,109.103444 11.8247236,107.371536 11.8247236,104.862069 C11.8247236,103.153495 11.7048796,101.838714 11.4651881,100.917686 C11.2254966,99.9966584 10.6728827,99.5361513 9.80732989,99.5361513 C9.22141723,99.5361513 8.62219737,99.843156 8.00965231,100.457175 C7.51695303,100.951059 7.07752513,101.197998 6.69135542,101.197998 C6.3584505,101.197998 6.08880156,101.051169 5.88240051,100.757508 C5.67599946,100.463847 5.57280049,100.183539 5.57280049,99.916574 C5.57280049,99.5962164 5.67599946,99.3225818 5.88240051,99.0956618 C6.08880156,98.8687419 6.57150646,98.5016711 7.33052967,97.9944383 C10.2068282,96.0722929 11.6449559,93.9766521 11.6449559,91.7074527 C11.6449559,90.5194601 11.3386879,89.615131 10.7261429,88.9944383 C10.1135978,88.3737455 9.37455999,88.0634038 8.5090072,88.0634038 C7.71003539,88.0634038 6.98431355,88.3270274 6.33181991,88.8542825 C5.67932627,89.3815377 5.35308434,90.0122321 5.35308434,90.7463849 C5.35308434,91.3871 5.60608828,91.9810874 6.11210376,92.5283648 C6.28521432,92.7285883 6.3717683,92.8954387 6.3717683,93.028921 C6.3717683,93.1490551 5.80250943,93.4560598 4.6639746,93.9499444 C3.52543978,94.4438289 2.80970494,94.6907675 2.51674861,94.6907675 C2.10394651,94.6907675 1.76771758,94.3570667 1.50805174,93.6896552 C1.24838591,93.0222436 1.11855494,92.4082342 1.11855494,91.8476085 C1.11855494,90.0989901 2.04734573,88.6240327 3.90495518,87.4226919 C5.76256463,86.2213511 7.86982116,85.6206897 10.226788,85.6206897 C12.2907985,85.6206897 14.0784711,86.0678487 15.5898594,86.9621802 C17.1012478,87.8565117 17.8569306,89.0778566 17.8569306,90.6262514 C17.8569306,91.987771 17.2876717,93.2491599 16.1491369,94.4104561 C15.0106021,95.5717522 13.6956474,96.4994404 12.2042333,97.1935484 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/list": {
"title": "$:/core/images/list",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-list tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M0.719999312,185.568543 C2.21955287,181.862817 3.0452019,177.812144 3.0452019,173.568542 C3.0452019,155.891545 -11.2816707,141.568542 -28.9547636,141.568542 L-60.9548326,141.568542 C-78.6344937,141.568542 -92.9547981,155.895431 -92.9547981,173.568542 C-92.9547981,191.24554 -78.6279255,205.568542 -60.9548326,205.568542 L-28.9547636,205.568542 C-27.593228,205.568542 -26.2516158,205.483573 -24.9349335,205.31865 C-31.5207556,201.78951 -36.8809788,196.272192 -40.2126959,189.568542 L-60.9493786,189.568542 C-69.7889277,189.568542 -76.9547981,182.407041 -76.9547981,173.568542 C-76.9547981,164.731986 -69.7994766,157.568542 -60.9493786,157.568542 L-28.9602176,157.568542 C-20.1206685,157.568542 -12.9547981,164.730044 -12.9547981,173.568542 C-12.9547981,176.946528 -14.0004297,180.080016 -15.7866505,182.6623 C-13.6856165,184.473592 -10.949961,185.568542 -7.9585771,185.568542 L0.720002586,185.568542 Z\" transform=\"translate(-44.954798, 173.568542) rotate(-225.000000) translate(44.954798, -173.568542) \"></path>\n <path d=\"M87.7480315,128 L23.9992458,128 C19.5813843,128 16,124.409247 16,119.993027 L16,8.00697327 C16,3.58484404 19.5881049,0 23.9992458,0 L104.000754,0 C108.418616,0 112,3.59075293 112,8.00697327 L112,104 L91.2492027,104 C90.2848199,104 89.410573,104.391703 88.7768998,105.025201 C88.1373658,105.661376 87.7480315,106.53563 87.7480315,107.501171 L87.7480315,128 Z M95.7480315,127.879386 L111.627417,112 L95.7480315,112 L95.7480315,127.879386 Z M40,15.5089165 C40,13.5709954 41.5636015,12 43.4998101,12 L98.5001899,12 C100.433082,12 102,13.5614718 102,15.5089165 L102,16.4910835 C102,18.4290046 100.436399,20 98.5001899,20 L43.4998101,20 C41.5669183,20 40,18.4385282 40,16.4910835 L40,15.5089165 Z M32,22 C35.3137085,22 38,19.3137085 38,16 C38,12.6862915 35.3137085,10 32,10 C28.6862915,10 26,12.6862915 26,16 C26,19.3137085 28.6862915,22 32,22 Z M40,31.5089165 C40,29.5709954 41.5636015,28 43.4998101,28 L98.5001899,28 C100.433082,28 102,29.5614718 102,31.5089165 L102,32.4910835 C102,34.4290046 100.436399,36 98.5001899,36 L43.4998101,36 C41.5669183,36 40,34.4385282 40,32.4910835 L40,31.5089165 Z M40,47.5089165 C40,45.5709954 41.5636015,44 43.4998101,44 L98.5001899,44 C100.433082,44 102,45.5614718 102,47.5089165 L102,48.4910835 C102,50.4290046 100.436399,52 98.5001899,52 L43.4998101,52 C41.5669183,52 40,50.4385282 40,48.4910835 L40,47.5089165 Z M40,63.5089165 C40,61.5709954 41.5636015,60 43.4998101,60 L98.5001899,60 C100.433082,60 102,61.5614718 102,63.5089165 L102,64.4910835 C102,66.4290046 100.436399,68 98.5001899,68 L43.4998101,68 C41.5669183,68 40,66.4385282 40,64.4910835 L40,63.5089165 Z M40,79.5089165 C40,77.5709954 41.5636015,76 43.4998101,76 L98.5001899,76 C100.433082,76 102,77.5614718 102,79.5089165 L102,80.4910835 C102,82.4290046 100.436399,84 98.5001899,84 L43.4998101,84 C41.5669183,84 40,82.4385282 40,80.4910835 L40,79.5089165 Z M40,95.5089165 C40,93.5709954 41.5636015,92 43.4998101,92 L98.5001899,92 C100.433082,92 102,93.5614718 102,95.5089165 L102,96.4910835 C102,98.4290046 100.436399,100 98.5001899,100 L43.4998101,100 C41.5669183,100 40,98.4385282 40,96.4910835 L40,95.5089165 Z M40,111.508916 C40,109.570995 41.5680474,108 43.4972017,108 L76.5027983,108 C78.4342495,108 80,109.561472 80,111.508916 L80,112.491084 C80,114.429005 78.4319526,116 76.5027983,116 L43.4972017,116 C41.5657505,116 40,114.438528 40,112.491084 L40,111.508916 Z M32,38 C35.3137085,38 38,35.3137085 38,32 C38,28.6862915 35.3137085,26 32,26 C28.6862915,26 26,28.6862915 26,32 C26,35.3137085 28.6862915,38 32,38 Z M32,54 C35.3137085,54 38,51.3137085 38,48 C38,44.6862915 35.3137085,42 32,42 C28.6862915,42 26,44.6862915 26,48 C26,51.3137085 28.6862915,54 32,54 Z M32,70 C35.3137085,70 38,67.3137085 38,64 C38,60.6862915 35.3137085,58 32,58 C28.6862915,58 26,60.6862915 26,64 C26,67.3137085 28.6862915,70 32,70 Z M32,86 C35.3137085,86 38,83.3137085 38,80 C38,76.6862915 35.3137085,74 32,74 C28.6862915,74 26,76.6862915 26,80 C26,83.3137085 28.6862915,86 32,86 Z M32,102 C35.3137085,102 38,99.3137085 38,96 C38,92.6862915 35.3137085,90 32,90 C28.6862915,90 26,92.6862915 26,96 C26,99.3137085 28.6862915,102 32,102 Z M32,118 C35.3137085,118 38,115.313708 38,112 C38,108.686292 35.3137085,106 32,106 C28.6862915,106 26,108.686292 26,112 C26,115.313708 28.6862915,118 32,118 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/locked-padlock": {
"title": "$:/core/images/locked-padlock",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-locked-padlock tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M96.4723753,64 L105,64 L105,96.0097716 C105,113.673909 90.6736461,128 73.001193,128 L55.998807,128 C38.3179793,128 24,113.677487 24,96.0097716 L24,64 L32.0000269,64 C32.0028554,48.2766389 32.3030338,16.2688026 64.1594984,16.2688041 C95.9543927,16.2688056 96.4648869,48.325931 96.4723753,64 Z M80.5749059,64 L48.4413579,64 C48.4426205,47.71306 48.5829272,31.9999996 64.1595001,31.9999996 C79.8437473,31.9999996 81.1369461,48.1359182 80.5749059,64 Z M67.7315279,92.3641717 C70.8232551,91.0923621 73,88.0503841 73,84.5 C73,79.8055796 69.1944204,76 64.5,76 C59.8055796,76 56,79.8055796 56,84.5 C56,87.947435 58.0523387,90.9155206 61.0018621,92.2491029 L55.9067479,115.020857 L72.8008958,115.020857 L67.7315279,92.3641717 L67.7315279,92.3641717 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/mail": {
"title": "$:/core/images/mail",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-mail tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M122.826782,104.894066 C121.945525,105.22777 120.990324,105.41043 119.993027,105.41043 L8.00697327,105.41043 C7.19458381,105.41043 6.41045219,105.289614 5.67161357,105.064967 L5.67161357,105.064967 L39.8346483,70.9019325 L60.6765759,91.7438601 C61.6118278,92.679112 62.8865166,93.0560851 64.0946097,92.8783815 C65.2975108,93.0473238 66.5641085,92.6696979 67.4899463,91.7438601 L88.5941459,70.6396605 C88.6693095,70.7292352 88.7490098,70.8162939 88.8332479,70.9005321 L122.826782,104.894066 Z M127.903244,98.6568194 C127.966933,98.2506602 128,97.8343714 128,97.4103789 L128,33.410481 C128,32.7414504 127.917877,32.0916738 127.763157,31.4706493 L94.2292399,65.0045665 C94.3188145,65.0797417 94.4058701,65.1594458 94.4901021,65.2436778 L127.903244,98.6568194 Z M0.205060636,99.2178117 C0.0709009529,98.6370366 0,98.0320192 0,97.4103789 L0,33.410481 C0,32.694007 0.0944223363,31.9995312 0.27147538,31.3387595 L0.27147538,31.3387595 L34.1777941,65.2450783 L0.205060636,99.2178117 L0.205060636,99.2178117 Z M5.92934613,25.6829218 C6.59211333,25.5051988 7.28862283,25.4104299 8.00697327,25.4104299 L119.993027,25.4104299 C120.759109,25.4104299 121.500064,25.5178649 122.201605,25.7184927 L122.201605,25.7184927 L64.0832611,83.8368368 L5.92934613,25.6829218 L5.92934613,25.6829218 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/menu-button": {
"title": "$:/core/images/menu-button",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-menu-button tc-image-button\" viewBox=\"0 0 128 128\" width=\"22pt\" height=\"22pt\">\n <rect x=\"0\" y=\"16\" width=\"128\" height=\"16\" rx=\"8\"></rect>\n <rect x=\"0\" y=\"56\" width=\"128\" height=\"16\" rx=\"8\"></rect>\n <rect x=\"0\" y=\"96\" width=\"128\" height=\"16\" rx=\"8\"></rect>\n</svg>"
},
"$:/core/images/mono-block": {
"title": "$:/core/images/mono-block",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-mono-block tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M23.9653488,32.9670593 L24.3217888,32.9670593 C25.0766067,32.9670593 25.6497006,33.1592554 26.0410876,33.5436534 C26.4324747,33.9280514 26.6281653,34.4906619 26.6281653,35.2315017 C26.6281653,36.0562101 26.4219913,36.6502709 26.009637,37.0137017 C25.5972828,37.3771326 24.9158602,37.5588453 23.9653488,37.5588453 L17.6542639,37.5588453 C16.6897744,37.5588453 16.0048573,37.380627 15.5994921,37.0241852 C15.1941269,36.6677435 14.9914474,36.0701882 14.9914474,35.2315017 C14.9914474,34.4207713 15.1941269,33.8406885 15.5994921,33.4912358 C16.0048573,33.141783 16.6897744,32.9670593 17.6542639,32.9670593 L18.388111,32.9670593 L17.5284616,30.5139133 L8.47069195,30.5139133 L7.5691084,32.9670593 L8.30295547,32.9670593 C9.25346691,32.9670593 9.93488953,33.1452775 10.3472438,33.5017193 C10.759598,33.8581611 10.965772,34.4347494 10.965772,35.2315017 C10.965772,36.0562101 10.759598,36.6502709 10.3472438,37.0137017 C9.93488953,37.3771326 9.25346691,37.5588453 8.30295547,37.5588453 L2.89345418,37.5588453 C1.92896463,37.5588453 1.24404754,37.3771326 0.838682371,37.0137017 C0.433317198,36.6502709 0.230637652,36.0562101 0.230637652,35.2315017 C0.230637652,34.4906619 0.426328248,33.9280514 0.817715312,33.5436534 C1.20910238,33.1592554 1.78219626,32.9670593 2.53701417,32.9670593 L2.89345418,32.9670593 L8.51262607,17.3256331 L6.83526132,17.3256331 C5.88474988,17.3256331 5.20332727,17.1439204 4.79097304,16.7804895 C4.37861882,16.4170587 4.1724448,15.8299869 4.1724448,15.0192565 C4.1724448,14.1945481 4.37861882,13.6004873 4.79097304,13.2370565 C5.20332727,12.8736257 5.88474988,12.691913 6.83526132,12.691913 L14.6979086,12.691913 C15.9419603,12.691913 16.815579,13.3628521 17.318791,14.7047506 L17.318791,14.7676518 L23.9653488,32.9670593 Z M12.9786097,17.3256331 L9.9383861,26.1737321 L16.0188333,26.1737321 L12.9786097,17.3256331 Z M35.3809383,26.6979086 L35.3809383,33.0928616 L38.5259972,33.0928616 C40.7485166,33.0928616 42.3140414,32.8482484 43.2226185,32.3590146 C44.1311956,31.8697807 44.5854773,31.0520736 44.5854773,29.9058686 C44.5854773,28.7456855 44.1521624,27.9209895 43.2855197,27.4317556 C42.4188769,26.9425218 40.9022748,26.6979086 38.7356678,26.6979086 L35.3809383,26.6979086 Z M46.0741385,24.370565 C47.5977525,24.9296893 48.7159844,25.6949794 49.428868,26.666458 C50.1417516,27.6379366 50.498188,28.8784752 50.498188,30.388111 C50.498188,31.6601189 50.1906743,32.8202846 49.5756374,33.8686428 C48.9606006,34.917001 48.0799929,35.7766419 46.933788,36.4475911 C46.2628387,36.8389782 45.5115266,37.1220307 44.6798291,37.296757 C43.8481316,37.4714834 42.6704935,37.5588453 41.1468796,37.5588453 L39.3856466,37.5588453 L30.2020747,37.5588453 C29.2795194,37.5588453 28.6190637,37.3771326 28.2206876,37.0137017 C27.8223114,36.6502709 27.6231264,36.0562101 27.6231264,35.2315017 C27.6231264,34.4906619 27.811828,33.9280514 28.189237,33.5436534 C28.5666459,33.1592554 29.118773,32.9670593 29.8456347,32.9670593 L30.2020747,32.9670593 L30.2020747,17.3256331 L29.8456347,17.3256331 C29.118773,17.3256331 28.5666459,17.1299425 28.189237,16.7385554 C27.811828,16.3471683 27.6231264,15.7740744 27.6231264,15.0192565 C27.6231264,14.2085262 27.8258059,13.6179599 28.2311711,13.24754 C28.6365363,12.8771201 29.2934976,12.691913 30.2020747,12.691913 L39.8469219,12.691913 C42.796303,12.691913 45.0362615,13.2650068 46.5668644,14.4112118 C48.0974674,15.5574168 48.8627574,17.2347648 48.8627574,19.443306 C48.8627574,20.5335986 48.6286276,21.4945792 48.1603609,22.3262767 C47.6920943,23.1579742 46.9966938,23.8393968 46.0741385,24.370565 L46.0741385,24.370565 Z M35.3809383,17.1998307 L35.3809383,22.4835296 L38.2114913,22.4835296 C39.9307988,22.4835296 41.1433816,22.2808501 41.8492761,21.8754849 C42.5551706,21.4701197 42.9081126,20.7852027 42.9081126,19.8207131 C42.9081126,18.912136 42.5901154,18.2481858 41.9541114,17.8288425 C41.3181074,17.4094992 40.2872373,17.1998307 38.8614701,17.1998307 L35.3809383,17.1998307 Z M71.244119,13.3838259 C71.5236812,12.880614 71.8102281,12.5241775 72.1037684,12.3145059 C72.3973087,12.1048342 72.7677231,12 73.2150226,12 C73.8999499,12 74.3856819,12.1817127 74.6722332,12.5451435 C74.9587844,12.9085744 75.1020579,13.5305909 75.1020579,14.4112118 L75.143992,19.8626472 C75.143992,20.8271368 74.9867406,21.4771091 74.6722332,21.8125837 C74.3577257,22.1480584 73.7881263,22.3157932 72.9634178,22.3157932 C72.3763372,22.3157932 71.92555,22.1760142 71.6110425,21.896452 C71.2965351,21.6168898 71.0274605,21.0997075 70.8038107,20.3448896 C70.4403799,19.0169692 69.8602971,18.0629775 69.0635448,17.482886 C68.2667926,16.9027945 67.1625385,16.612753 65.7507494,16.612753 C63.5981206,16.612753 61.9487284,17.3396038 60.8025235,18.7933272 C59.6563185,20.2470506 59.0832246,22.3507245 59.0832246,25.104412 C59.0832246,27.8441215 59.6633074,29.9477954 60.8234905,31.4154969 C61.9836736,32.8831984 63.6400547,33.6170381 65.7926836,33.6170381 C67.2603851,33.6170381 68.878327,33.1278116 70.6465578,32.149344 C72.4147886,31.1708763 73.5295261,30.6816498 73.9908037,30.6816498 C74.53595,30.6816498 74.9937262,30.9122852 75.3641461,31.3735628 C75.734566,31.8348404 75.9197732,32.4079343 75.9197732,33.0928616 C75.9197732,34.3229353 74.836486,35.4831009 72.669879,36.5733935 C70.5032721,37.663686 68.0641285,38.2088241 65.3523753,38.2088241 C61.6901107,38.2088241 58.7267959,36.9997358 56.4623422,34.5815228 C54.1978885,32.1633099 53.0656786,29.0043046 53.0656786,25.104412 C53.0656786,21.3443006 54.2118664,18.22024 56.5042763,15.7321366 C58.7966863,13.2440331 61.7040894,12 65.226573,12 C66.2190187,12 67.1974717,12.1118232 68.1619613,12.3354729 C69.1264508,12.5591227 70.1538264,12.9085702 71.244119,13.3838259 L71.244119,13.3838259 Z M81.4645862,32.9670593 L81.4645862,17.3256331 L81.1081461,17.3256331 C80.3533282,17.3256331 79.7802344,17.1299425 79.3888473,16.7385554 C78.9974602,16.3471683 78.8017696,15.7740744 78.8017696,15.0192565 C78.8017696,14.2085262 79.0114381,13.6179599 79.4307814,13.24754 C79.8501247,12.8771201 80.5280528,12.691913 81.4645862,12.691913 L85.4063933,12.691913 L86.6434498,12.691913 C89.5648747,12.691913 91.7034933,12.8177141 93.0593699,13.06932 C94.4152465,13.320926 95.5684233,13.740263 96.5189347,14.3273436 C98.210286,15.3337675 99.5067362,16.7699967 100.408324,18.6360743 C101.309912,20.5021519 101.7607,22.6582429 101.7607,25.104412 C101.7607,27.6903623 101.247012,29.9512876 100.219621,31.8872557 C99.1922296,33.8232239 97.7350336,35.2874089 95.8479888,36.2798546 C94.9953241,36.7271541 93.9959043,37.0521403 92.8496993,37.2548229 C91.7034944,37.4575055 89.9981906,37.5588453 87.7337369,37.5588453 L85.4063933,37.5588453 L81.4645862,37.5588453 C80.5000966,37.5588453 79.8151795,37.380627 79.4098143,37.0241852 C79.0044492,36.6677435 78.8017696,36.0701882 78.8017696,35.2315017 C78.8017696,34.4906619 78.9974602,33.9280514 79.3888473,33.5436534 C79.7802344,33.1592554 80.3533282,32.9670593 81.1081461,32.9670593 L81.4645862,32.9670593 Z M86.8740874,17.2417648 L86.8740874,32.9670593 L88.0692098,32.9670593 C90.7110725,32.9670593 92.6609895,32.3205814 93.9190194,31.0276063 C95.1770492,29.7346312 95.8060547,27.7462749 95.8060547,25.0624779 C95.8060547,22.4206153 95.1665658,20.4497314 93.8875688,19.1497672 C92.6085718,17.849803 90.6831161,17.1998307 88.1111439,17.1998307 C87.7756693,17.1998307 87.5205727,17.2033252 87.3458463,17.2103142 C87.1711199,17.2173033 87.0138685,17.2277867 86.8740874,17.2417648 L86.8740874,17.2417648 Z M121.94052,17.1159625 L112.190837,17.1159625 L112.190837,22.4835296 L115.88104,22.4835296 L115.88104,22.2319249 C115.88104,21.4351727 116.055763,20.841112 116.405216,20.4497249 C116.754669,20.0583378 117.285829,19.8626472 117.998713,19.8626472 C118.627728,19.8626472 119.141415,20.0408655 119.539792,20.3973072 C119.938168,20.753749 120.137353,21.2045363 120.137353,21.7496826 C120.137353,21.7776388 120.144342,21.8684951 120.15832,22.0222543 C120.172298,22.1760135 120.179287,22.3297704 120.179287,22.4835296 L120.179287,26.8237109 C120.179287,27.7602442 120.011552,28.4311834 119.676077,28.8365486 C119.340603,29.2419138 118.795465,29.4445933 118.040647,29.4445933 C117.327763,29.4445933 116.789614,29.2558917 116.426183,28.8784827 C116.062752,28.5010738 115.88104,27.9419578 115.88104,27.201118 L115.88104,26.8237109 L112.190837,26.8237109 L112.190837,33.0928616 L121.94052,33.0928616 L121.94052,30.5977816 C121.94052,29.6612482 122.118738,28.9903091 122.47518,28.5849439 C122.831622,28.1795787 123.415199,27.9768992 124.225929,27.9768992 C125.022682,27.9768992 125.592281,28.1760842 125.934745,28.5744604 C126.277208,28.9728365 126.448438,29.6472701 126.448438,30.5977816 L126.448438,35.6718099 C126.448438,36.4266278 126.30167,36.9298322 126.008129,37.1814382 C125.714589,37.4330442 125.134506,37.5588453 124.267863,37.5588453 L107.095842,37.5588453 C106.173287,37.5588453 105.512831,37.3771326 105.114455,37.0137017 C104.716079,36.6502709 104.516894,36.0562101 104.516894,35.2315017 C104.516894,34.4906619 104.705595,33.9280514 105.083004,33.5436534 C105.460413,33.1592554 106.01254,32.9670593 106.739402,32.9670593 L107.095842,32.9670593 L107.095842,17.3256331 L106.739402,17.3256331 C106.026518,17.3256331 105.477886,17.126448 105.093488,16.7280719 C104.70909,16.3296957 104.516894,15.7600963 104.516894,15.0192565 C104.516894,14.2085262 104.719573,13.6179599 105.124938,13.24754 C105.530304,12.8771201 106.187265,12.691913 107.095842,12.691913 L124.267863,12.691913 C125.120528,12.691913 125.697116,12.8212085 125.997646,13.0798036 C126.298175,13.3383986 126.448438,13.8520864 126.448438,14.6208824 L126.448438,19.3175037 C126.448438,20.2680151 126.273714,20.9494377 125.924261,21.361792 C125.574808,21.7741462 125.008703,21.9803202 124.225929,21.9803202 C123.415199,21.9803202 122.831622,21.7706517 122.47518,21.3513084 C122.118738,20.9319652 121.94052,20.254037 121.94052,19.3175037 L121.94052,17.1159625 Z M19.7719369,47.6405477 C20.037521,47.1373358 20.3205734,46.7808993 20.6211028,46.5712277 C20.9216322,46.361556 21.295541,46.2567218 21.7428405,46.2567218 C22.4277678,46.2567218 22.9134998,46.4384345 23.2000511,46.8018653 C23.4866023,47.1652962 23.6298758,47.7873127 23.6298758,48.6679336 L23.6718099,54.119369 C23.6718099,55.0838586 23.5145586,55.7338309 23.2000511,56.0693055 C22.8855436,56.4047802 22.3089553,56.572515 21.4702687,56.572515 C20.8831881,56.572515 20.4254119,56.4292415 20.0969263,56.1426902 C19.7684407,55.856139 19.4993662,55.3424512 19.2896945,54.6016114 C18.9122856,53.2597129 18.3322027,52.3022267 17.5494286,51.7291243 C16.7666545,51.1560218 15.6693894,50.8694748 14.2576003,50.8694748 C12.1049715,50.8694748 10.4590738,51.5963256 9.31985785,53.050049 C8.18064193,54.5037724 7.61104252,56.6074463 7.61104252,59.3611338 C7.61104252,62.1148214 8.20859773,64.2429566 9.40372609,65.7456034 C10.5988544,67.2482501 12.2936748,67.9995623 14.488238,67.9995623 C14.9914499,67.9995623 15.5645438,67.9401562 16.2075368,67.8213423 C16.8505299,67.7025283 17.6053364,67.5173212 18.4719792,67.2657152 L18.4719792,63.9529198 L16.1027015,63.9529198 C15.1521901,63.9529198 14.4777564,63.7781961 14.0793803,63.4287433 C13.6810042,63.0792906 13.4818191,62.4992078 13.4818191,61.6884774 C13.4818191,60.8497908 13.6810042,60.2522356 14.0793803,59.8957938 C14.4777564,59.5393521 15.1521901,59.3611338 16.1027015,59.3611338 L23.6718099,59.3611338 C24.6502776,59.3611338 25.3386891,59.5358576 25.7370653,59.8853103 C26.1354414,60.2347631 26.3346265,60.8218348 26.3346265,61.6465433 C26.3346265,62.3873831 26.1354414,62.9569825 25.7370653,63.3553586 C25.3386891,63.7537347 24.7621008,63.9529198 24.0072829,63.9529198 L23.6718099,63.9529198 L23.6718099,68.9430799 L23.6718099,69.1946846 C23.6718099,69.6419841 23.6228873,69.9529924 23.5250405,70.1277188 C23.4271937,70.3024451 23.2315031,70.4806634 22.9379628,70.6623788 C22.1412106,71.1376345 20.8762107,71.5569715 19.1429251,71.9204023 C17.4096396,72.2838332 15.6554131,72.4655459 13.8801932,72.4655459 C10.2179286,72.4655459 7.25461383,71.2564576 4.99016011,68.8382446 C2.72570638,66.4200317 1.59349651,63.2610264 1.59349651,59.3611338 C1.59349651,55.6010224 2.73968428,52.4769618 5.03209423,49.9888583 C7.32450417,47.5007549 10.2319073,46.2567218 13.7543909,46.2567218 C14.7328585,46.2567218 15.7078171,46.368545 16.6792957,46.5921947 C17.6507743,46.8158445 18.6816444,47.165292 19.7719369,47.6405477 L19.7719369,47.6405477 Z M35.611576,51.5823548 L35.611576,56.4047785 L42.4678043,56.4047785 L42.4678043,51.5823548 L42.1323314,51.5823548 C41.3775135,51.5823548 40.8009251,51.3866642 40.402549,50.9952772 C40.0041729,50.6038901 39.8049878,50.0307962 39.8049878,49.2759783 C39.8049878,48.4512699 40.0111618,47.8572091 40.4235161,47.4937783 C40.8358703,47.1303474 41.5172929,46.9486347 42.4678043,46.9486347 L47.8773056,46.9486347 C48.8278171,46.9486347 49.5022507,47.1303474 49.9006269,47.4937783 C50.299003,47.8572091 50.498188,48.4512699 50.498188,49.2759783 C50.498188,50.0307962 50.3059919,50.6038901 49.9215939,50.9952772 C49.5371959,51.3866642 48.9745854,51.5823548 48.2337456,51.5823548 L47.8773056,51.5823548 L47.8773056,67.2237811 L48.2337456,67.2237811 C48.9885636,67.2237811 49.5616574,67.4159772 49.9530445,67.8003752 C50.3444316,68.1847732 50.5401222,68.7473837 50.5401222,69.4882235 C50.5401222,70.3129319 50.3374426,70.9069927 49.9320774,71.2704235 C49.5267123,71.6338543 48.8417952,71.815567 47.8773056,71.815567 L42.4678043,71.815567 C41.5033148,71.815567 40.8183977,71.6373488 40.4130325,71.280907 C40.0076674,70.9244652 39.8049878,70.32691 39.8049878,69.4882235 C39.8049878,68.7473837 40.0041729,68.1847732 40.402549,67.8003752 C40.8009251,67.4159772 41.3775135,67.2237811 42.1323314,67.2237811 L42.4678043,67.2237811 L42.4678043,61.0384986 L35.611576,61.0384986 L35.611576,67.2237811 L35.9470489,67.2237811 C36.7018668,67.2237811 37.2784552,67.4159772 37.6768313,67.8003752 C38.0752074,68.1847732 38.2743925,68.7473837 38.2743925,69.4882235 C38.2743925,70.3129319 38.0682185,70.9069927 37.6558642,71.2704235 C37.24351,71.6338543 36.5620874,71.815567 35.611576,71.815567 L30.2020747,71.815567 C29.2375851,71.815567 28.552668,71.6373488 28.1473029,71.280907 C27.7419377,70.9244652 27.5392581,70.32691 27.5392581,69.4882235 C27.5392581,68.7473837 27.7349487,68.1847732 28.1263358,67.8003752 C28.5177229,67.4159772 29.0908168,67.2237811 29.8456347,67.2237811 L30.2020747,67.2237811 L30.2020747,51.5823548 L29.8456347,51.5823548 C29.1047949,51.5823548 28.5421844,51.3866642 28.1577864,50.9952772 C27.7733884,50.6038901 27.5811923,50.0307962 27.5811923,49.2759783 C27.5811923,48.4512699 27.7803773,47.8572091 28.1787534,47.4937783 C28.5771296,47.1303474 29.2515632,46.9486347 30.2020747,46.9486347 L35.611576,46.9486347 C36.5481093,46.9486347 37.2260374,47.1303474 37.6453807,47.4937783 C38.064724,47.8572091 38.2743925,48.4512699 38.2743925,49.2759783 C38.2743925,50.0307962 38.0752074,50.6038901 37.6768313,50.9952772 C37.2784552,51.3866642 36.7018668,51.5823548 35.9470489,51.5823548 L35.611576,51.5823548 Z M67.365213,51.5823548 L67.365213,67.2237811 L70.887679,67.2237811 C71.8381904,67.2237811 72.519613,67.4019993 72.9319673,67.7584411 C73.3443215,68.1148829 73.5504955,68.6914712 73.5504955,69.4882235 C73.5504955,70.2989538 73.340827,70.8895201 72.9214837,71.25994 C72.5021404,71.6303599 71.8242123,71.815567 70.887679,71.815567 L58.4332458,71.815567 C57.4827343,71.815567 56.8013117,71.6338543 56.3889575,71.2704235 C55.9766033,70.9069927 55.7704292,70.3129319 55.7704292,69.4882235 C55.7704292,68.6774931 55.9731088,68.0974103 56.378474,67.7479575 C56.7838391,67.3985048 57.4687562,67.2237811 58.4332458,67.2237811 L61.9557117,67.2237811 L61.9557117,51.5823548 L58.4332458,51.5823548 C57.4827343,51.5823548 56.8013117,51.4006421 56.3889575,51.0372113 C55.9766033,50.6737805 55.7704292,50.0867087 55.7704292,49.2759783 C55.7704292,48.4512699 55.9731088,47.8641981 56.378474,47.5147453 C56.7838391,47.1652926 57.4687562,46.9905689 58.4332458,46.9905689 L70.887679,46.9905689 C71.8801247,46.9905689 72.5720308,47.1652926 72.9634178,47.5147453 C73.3548049,47.8641981 73.5504955,48.4512699 73.5504955,49.2759783 C73.5504955,50.0867087 73.347816,50.6737805 72.9424508,51.0372113 C72.5370856,51.4006421 71.8521685,51.5823548 70.887679,51.5823548 L67.365213,51.5823548 Z M97.8608265,51.5823548 L97.8608265,63.1771386 L97.8608265,63.5755127 C97.8608265,65.4485794 97.7385199,66.8044357 97.493903,67.6431222 C97.2492861,68.4818088 96.8404325,69.2296264 96.26733,69.8865976 C95.5264902,70.7392623 94.4991146,71.3822457 93.1851723,71.815567 C91.87123,72.2488884 90.2917273,72.4655459 88.4466169,72.4655459 C87.1466527,72.4655459 85.8921362,72.3397448 84.6830298,72.0881388 C83.4739233,71.8365328 82.3102631,71.4591296 81.1920144,70.9559176 C80.5769776,70.6763554 80.175113,70.31293 79.9864085,69.8656305 C79.797704,69.418331 79.7033532,68.6914802 79.7033532,67.6850564 L79.7033532,63.3658422 C79.7033532,62.1637247 79.8780769,61.3250508 80.2275297,60.849795 C80.5769824,60.3745393 81.185021,60.136915 82.0516638,60.136915 C83.2957156,60.136915 83.9806326,61.0524675 84.1064356,62.8835998 C84.1204137,63.2050963 84.1413806,63.4497096 84.1693368,63.6174469 C84.3370741,65.2389076 84.7144774,66.3466561 85.301558,66.9407258 C85.8886386,67.5347954 86.8251579,67.8318258 88.1111439,67.8318258 C89.7046484,67.8318258 90.8263749,67.4089943 91.476357,66.5633187 C92.126339,65.7176431 92.4513252,64.1765796 92.4513252,61.9400821 L92.4513252,51.5823548 L88.9288593,51.5823548 C87.9783478,51.5823548 87.2969252,51.4006421 86.884571,51.0372113 C86.4722168,50.6737805 86.2660427,50.0867087 86.2660427,49.2759783 C86.2660427,48.4512699 86.4652278,47.8641981 86.8636039,47.5147453 C87.26198,47.1652926 87.9503916,46.9905689 88.9288593,46.9905689 L99.6220595,46.9905689 C100.600527,46.9905689 101.288939,47.1652926 101.687315,47.5147453 C102.085691,47.8641981 102.284876,48.4512699 102.284876,49.2759783 C102.284876,50.0867087 102.078702,50.6737805 101.666348,51.0372113 C101.253994,51.4006421 100.572571,51.5823548 99.6220595,51.5823548 L97.8608265,51.5823548 Z M112.505343,51.5823548 L112.505343,57.9353738 L118.984165,51.4565525 C118.257303,51.3726838 117.747109,51.1665098 117.453569,50.8380242 C117.160029,50.5095387 117.013261,49.9888619 117.013261,49.2759783 C117.013261,48.4512699 117.212446,47.8572091 117.610822,47.4937783 C118.009198,47.1303474 118.683632,46.9486347 119.634143,46.9486347 L124.771073,46.9486347 C125.721584,46.9486347 126.396018,47.1303474 126.794394,47.4937783 C127.19277,47.8572091 127.391955,48.4512699 127.391955,49.2759783 C127.391955,50.0447743 127.19277,50.6213627 126.794394,51.0057607 C126.396018,51.3901587 125.812441,51.5823548 125.043645,51.5823548 L124.561402,51.5823548 L118.459988,57.641835 C119.592215,58.4805215 120.626579,59.5812811 121.563113,60.9441468 C122.499646,62.3070125 123.596911,64.400203 124.854941,67.2237811 L125.127513,67.2237811 L125.546854,67.2237811 C126.371563,67.2237811 126.98659,67.4124827 127.391955,67.7898917 C127.79732,68.1673006 128,68.7334056 128,69.4882235 C128,70.3129319 127.793826,70.9069927 127.381472,71.2704235 C126.969118,71.6338543 126.287695,71.815567 125.337183,71.815567 L122.758235,71.815567 C121.626008,71.815567 120.710456,71.0537715 120.01155,69.5301576 C119.885747,69.2505954 119.787902,69.026949 119.718012,68.8592117 C118.795456,66.9022764 117.949793,65.3926632 117.180997,64.3303269 C116.412201,63.2679906 115.510627,62.2965265 114.476247,61.4159056 L112.505343,63.302941 L112.505343,67.2237811 L112.840816,67.2237811 C113.595634,67.2237811 114.172222,67.4159772 114.570599,67.8003752 C114.968975,68.1847732 115.16816,68.7473837 115.16816,69.4882235 C115.16816,70.3129319 114.961986,70.9069927 114.549631,71.2704235 C114.137277,71.6338543 113.455855,71.815567 112.505343,71.815567 L107.095842,71.815567 C106.131352,71.815567 105.446435,71.6373488 105.04107,71.280907 C104.635705,70.9244652 104.433025,70.32691 104.433025,69.4882235 C104.433025,68.7473837 104.628716,68.1847732 105.020103,67.8003752 C105.41149,67.4159772 105.984584,67.2237811 106.739402,67.2237811 L107.095842,67.2237811 L107.095842,51.5823548 L106.739402,51.5823548 C105.998562,51.5823548 105.435952,51.3866642 105.051554,50.9952772 C104.667156,50.6038901 104.474959,50.0307962 104.474959,49.2759783 C104.474959,48.4512699 104.674145,47.8572091 105.072521,47.4937783 C105.470897,47.1303474 106.14533,46.9486347 107.095842,46.9486347 L112.505343,46.9486347 C113.441877,46.9486347 114.119805,47.1303474 114.539148,47.4937783 C114.958491,47.8572091 115.16816,48.4512699 115.16816,49.2759783 C115.16816,50.0307962 114.968975,50.6038901 114.570599,50.9952772 C114.172222,51.3866642 113.595634,51.5823548 112.840816,51.5823548 L112.505343,51.5823548 Z M13.439885,96.325622 L17.4445933,84.4372993 C17.6961993,83.6545252 18.0456468,83.0849258 18.4929463,82.728484 C18.9402458,82.3720422 19.5343065,82.193824 20.2751463,82.193824 L23.5460076,82.193824 C24.496519,82.193824 25.1779416,82.3755367 25.5902958,82.7389675 C26.0026501,83.1023984 26.2088241,83.6964591 26.2088241,84.5211676 C26.2088241,85.2759855 26.009639,85.8490794 25.6112629,86.2404664 C25.2128868,86.6318535 24.6362984,86.8275441 23.8814805,86.8275441 L23.5460076,86.8275441 L24.1330852,102.46897 L24.4895252,102.46897 C25.2443431,102.46897 25.8104481,102.661166 26.187857,103.045564 C26.565266,103.429962 26.7539676,103.992573 26.7539676,104.733413 C26.7539676,105.558121 26.5547826,106.152182 26.1564064,106.515613 C25.7580303,106.879044 25.0835967,107.060756 24.1330852,107.060756 L19.4154969,107.060756 C18.4649855,107.060756 17.7905518,106.882538 17.3921757,106.526096 C16.9937996,106.169654 16.7946145,105.572099 16.7946145,104.733413 C16.7946145,103.992573 16.9868106,103.429962 17.3712086,103.045564 C17.7556066,102.661166 18.325206,102.46897 19.0800239,102.46897 L19.4154969,102.46897 L19.1219581,89.6790642 L16.0607674,99.1981091 C15.8371177,99.9109927 15.5191204,100.42468 15.1067662,100.739188 C14.694412,101.053695 14.1248126,101.210947 13.3979509,101.210947 C12.6710892,101.210947 12.0945008,101.053695 11.6681685,100.739188 C11.2418362,100.42468 10.91685,99.9109927 10.6932002,99.1981091 L7.65297664,89.6790642 L7.35943781,102.46897 L7.69491075,102.46897 C8.44972866,102.46897 9.01932808,102.661166 9.40372609,103.045564 C9.78812409,103.429962 9.98032022,103.992573 9.98032022,104.733413 C9.98032022,105.558121 9.77764067,106.152182 9.3722755,106.515613 C8.96691032,106.879044 8.29597114,107.060756 7.35943781,107.060756 L2.62088241,107.060756 C1.68434908,107.060756 1.01340989,106.879044 0.608044719,106.515613 C0.202679546,106.152182 0,105.558121 0,104.733413 C0,103.992573 0.192196121,103.429962 0.57659413,103.045564 C0.960992139,102.661166 1.53059155,102.46897 2.28540946,102.46897 L2.62088241,102.46897 L3.22892713,86.8275441 L2.89345418,86.8275441 C2.13863627,86.8275441 1.56204791,86.6318535 1.16367179,86.2404664 C0.765295672,85.8490794 0.5661106,85.2759855 0.5661106,84.5211676 C0.5661106,83.6964591 0.772284622,83.1023984 1.18463885,82.7389675 C1.59699308,82.3755367 2.27841569,82.193824 3.22892713,82.193824 L6.49978838,82.193824 C7.22665007,82.193824 7.81022738,82.3685477 8.25053783,82.7180005 C8.69084827,83.0674532 9.05077919,83.6405471 9.33034138,84.4372993 L13.439885,96.325622 Z M43.8935644,98.3803938 L43.8935644,86.8275441 L42.7403761,86.8275441 C41.8178209,86.8275441 41.1573651,86.6458314 40.758989,86.2824006 C40.3606129,85.9189697 40.1614278,85.3318979 40.1614278,84.5211676 C40.1614278,83.7104372 40.3606129,83.119871 40.758989,82.7494511 C41.1573651,82.3790312 41.8178209,82.193824 42.7403761,82.193824 L48.6950209,82.193824 C49.6035981,82.193824 50.2605593,82.3790312 50.6659245,82.7494511 C51.0712897,83.119871 51.2739692,83.7104372 51.2739692,84.5211676 C51.2739692,85.2620074 51.0817731,85.8316068 50.6973751,86.2299829 C50.3129771,86.628359 49.7643445,86.8275441 49.051461,86.8275441 L48.6950209,86.8275441 L48.6950209,105.865634 C48.6950209,106.522605 48.6251315,106.934953 48.4853504,107.10269 C48.3455693,107.270428 48.0310665,107.354295 47.5418327,107.354295 L45.4451268,107.354295 C44.7741775,107.354295 44.3024234,107.284406 44.0298503,107.144625 C43.7572771,107.004843 43.5231473,106.76023 43.3274538,106.410777 L34.6051571,91.0838571 L34.6051571,102.46897 L35.8212466,102.46897 C36.7298237,102.46897 37.379796,102.643694 37.7711831,102.993147 C38.1625701,103.3426 38.3582607,103.922682 38.3582607,104.733413 C38.3582607,105.558121 38.1590757,106.152182 37.7606995,106.515613 C37.3623234,106.879044 36.7158456,107.060756 35.8212466,107.060756 L29.8037005,107.060756 C28.8951234,107.060756 28.2381621,106.879044 27.832797,106.515613 C27.4274318,106.152182 27.2247522,105.558121 27.2247522,104.733413 C27.2247522,103.992573 27.4134539,103.429962 27.7908629,103.045564 C28.1682718,102.661166 28.7273878,102.46897 29.4682276,102.46897 L29.8037005,102.46897 L29.8037005,86.8275441 L29.4682276,86.8275441 C28.755344,86.8275441 28.203217,86.628359 27.8118299,86.2299829 C27.4204428,85.8316068 27.2247522,85.2620074 27.2247522,84.5211676 C27.2247522,83.7104372 27.4309263,83.119871 27.8432805,82.7494511 C28.2556347,82.3790312 28.9091015,82.193824 29.8037005,82.193824 L33.2422983,82.193824 C34.0670067,82.193824 34.6261227,82.3021527 34.919663,82.5188134 C35.2132033,82.7354741 35.5416839,83.1722835 35.9051148,83.8292546 L43.8935644,98.3803938 Z M64.6604624,86.3662688 C62.8572863,86.3662688 61.4420239,87.0931196 60.4146329,88.546843 C59.3872418,90.0005663 58.873554,92.0203728 58.873554,94.6063231 C58.873554,97.1922733 59.3907363,99.2190688 60.4251164,100.68677 C61.4594965,102.154472 62.8712644,102.888312 64.6604624,102.888312 C66.4636385,102.888312 67.8823953,102.157966 68.9167754,100.697254 C69.9511555,99.2365414 70.4683378,97.2062514 70.4683378,94.6063231 C70.4683378,92.0203728 69.95465,90.0005663 68.9272589,88.546843 C67.8998679,87.0931196 66.4776166,86.3662688 64.6604624,86.3662688 L64.6604624,86.3662688 Z M64.6604624,81.501911 C68.0990773,81.501911 70.929602,82.7319662 73.1521214,85.1921135 C75.3746408,87.6522607 76.4858838,90.7902992 76.4858838,94.6063231 C76.4858838,98.4503032 75.3816297,101.595331 73.1730884,104.0415 C70.9645471,106.487669 68.1270335,107.710735 64.6604624,107.710735 C61.2358256,107.710735 58.4053009,106.477185 56.1688034,104.010049 C53.9323059,101.542913 52.8140739,98.4083688 52.8140739,94.6063231 C52.8140739,90.7763211 53.9218224,87.6347881 56.1373528,85.1816299 C58.3528831,82.7284717 61.1938912,81.501911 64.6604624,81.501911 L64.6604624,81.501911 Z M87.4611651,98.1707232 L87.4611651,102.46897 L89.6207722,102.46897 C90.5293493,102.46897 91.1758272,102.643694 91.5602252,102.993147 C91.9446232,103.3426 92.1368193,103.922682 92.1368193,104.733413 C92.1368193,105.558121 91.9411287,106.152182 91.5497417,106.515613 C91.1583546,106.879044 90.5153712,107.060756 89.6207722,107.060756 L82.3661697,107.060756 C81.4436145,107.060756 80.7831587,106.879044 80.3847826,106.515613 C79.9864065,106.152182 79.7872214,105.558121 79.7872214,104.733413 C79.7872214,103.992573 79.9759231,103.429962 80.353332,103.045564 C80.730741,102.661166 81.282868,102.46897 82.0097297,102.46897 L82.3661697,102.46897 L82.3661697,86.8275441 L82.0097297,86.8275441 C81.2968461,86.8275441 80.7482136,86.628359 80.3638155,86.2299829 C79.9794175,85.8316068 79.7872214,85.2620074 79.7872214,84.5211676 C79.7872214,83.7104372 79.989901,83.119871 80.3952661,82.7494511 C80.8006313,82.3790312 81.4575926,82.193824 82.3661697,82.193824 L91.0255652,82.193824 C94.450202,82.193824 97.0396079,82.8507853 98.7938606,84.1647276 C100.548113,85.4786699 101.425227,87.414609 101.425227,89.972603 C101.425227,92.6703781 100.551608,94.7111515 98.8043442,96.0949843 C97.0570805,97.4788171 94.4641801,98.1707232 91.0255652,98.1707232 L87.4611651,98.1707232 Z M87.4611651,86.8275441 L87.4611651,93.4531348 L90.4384875,93.4531348 C92.0879044,93.4531348 93.328443,93.1735768 94.1601405,92.6144525 C94.9918381,92.0553281 95.4076806,91.2166541 95.4076806,90.0984053 C95.4076806,89.0500471 94.9778602,88.2428234 94.1182064,87.67671 C93.2585527,87.1105966 92.031992,86.8275441 90.4384875,86.8275441 L87.4611651,86.8275441 Z M114.727851,107.396229 L113.092421,109.03166 C113.69348,108.835966 114.284046,108.689198 114.864137,108.591352 C115.444229,108.493505 116.013828,108.444582 116.572953,108.444582 C117.677223,108.444582 118.840883,108.608823 120.063968,108.937308 C121.287053,109.265794 122.031376,109.430034 122.29696,109.430034 C122.744259,109.430034 123.327837,109.279772 124.047709,108.979242 C124.767582,108.678713 125.253314,108.52845 125.50492,108.52845 C126.02211,108.52845 126.45193,108.727636 126.794394,109.126012 C127.136858,109.524388 127.308087,110.024098 127.308087,110.625156 C127.308087,111.421909 126.836333,112.099837 125.892811,112.658961 C124.949288,113.218086 123.792617,113.497643 122.422762,113.497643 C121.486229,113.497643 120.28413,113.277492 118.816428,112.837181 C117.348727,112.396871 116.286406,112.176719 115.629435,112.176719 C114.636989,112.176719 113.518757,112.449288 112.274706,112.994434 C111.030654,113.53958 110.261869,113.812149 109.968329,113.812149 C109.36727,113.812149 108.857077,113.612964 108.437734,113.214588 C108.01839,112.816212 107.808722,112.337469 107.808722,111.778345 C107.808722,111.386958 107.941512,110.971115 108.207096,110.530805 C108.47268,110.090494 108.94094,109.520895 109.611889,108.821989 L111.729562,106.683349 C109.395218,105.830685 107.536157,104.29661 106.152324,102.08108 C104.768491,99.8655494 104.076585,97.3180772 104.076585,94.4385866 C104.076585,90.6365409 105.180839,87.5299526 107.389381,85.1187288 C109.597922,82.7075049 112.442425,81.501911 115.922974,81.501911 C119.389545,81.501911 122.227059,82.7109994 124.4356,85.1292123 C126.644141,87.5474252 127.748395,90.650519 127.748395,94.4385866 C127.748395,98.2126762 126.65113,101.322759 124.456567,103.768928 C122.262004,106.215097 119.480402,107.438163 116.111677,107.438163 C115.888028,107.438163 115.660887,107.434669 115.430248,107.42768 C115.199609,107.420691 114.965479,107.410207 114.727851,107.396229 L114.727851,107.396229 Z M115.922974,86.3662688 C114.119798,86.3662688 112.704535,87.0931196 111.677144,88.546843 C110.649753,90.0005663 110.136065,92.0203728 110.136065,94.6063231 C110.136065,97.1922733 110.653248,99.2190688 111.687628,100.68677 C112.722008,102.154472 114.133776,102.888312 115.922974,102.888312 C117.72615,102.888312 119.144907,102.157966 120.179287,100.697254 C121.213667,99.2365414 121.730849,97.2062514 121.730849,94.6063231 C121.730849,92.0203728 121.217161,90.0005663 120.18977,88.546843 C119.162379,87.0931196 117.740128,86.3662688 115.922974,86.3662688 L115.922974,86.3662688 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/mono-line": {
"title": "$:/core/images/mono-line",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-mono-line tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M60.4374591,84.522627 L61.3450888,84.522627 C63.2671377,84.522627 64.7264493,85.0120303 65.7230673,85.9908515 C66.7196852,86.9696727 67.2179868,88.4022896 67.2179868,90.288745 C67.2179868,92.3887615 66.6929905,93.9014625 65.6429823,94.8268935 C64.5929741,95.7523244 62.857817,96.215033 60.4374591,96.215033 L44.3670747,96.215033 C41.9111232,96.215033 40.1670679,95.7612227 39.1348565,94.8535884 C38.102645,93.9459542 37.586547,92.424355 37.586547,90.288745 C37.586547,88.2243221 38.102645,86.747214 39.1348565,85.8573766 C40.1670679,84.9675391 41.9111232,84.522627 44.3670747,84.522627 L46.235724,84.522627 L44.0467348,78.2759992 L20.9822627,78.2759992 L18.6864935,84.522627 L20.5551429,84.522627 C22.9755008,84.522627 24.7106579,84.9764373 25.7606661,85.8840716 C26.8106743,86.7917058 27.3356705,88.2599156 27.3356705,90.288745 C27.3356705,92.3887615 26.8106743,93.9014625 25.7606661,94.8268935 C24.7106579,95.7523244 22.9755008,96.215033 20.5551429,96.215033 L6.78052766,96.215033 C4.32457622,96.215033 2.58052094,95.7523244 1.54830946,94.8268935 C0.516097994,93.9014625 0,92.3887615 0,90.288745 C0,88.4022896 0.498301511,86.9696727 1.49491948,85.9908515 C2.49153745,85.0120303 3.95084902,84.522627 5.87289797,84.522627 L6.78052766,84.522627 L21.0890427,44.6937008 L16.8178442,44.6937008 C14.3974863,44.6937008 12.6623292,44.2309922 11.612321,43.3055613 C10.5623128,42.3801303 10.0373165,40.8852258 10.0373165,38.8208028 C10.0373165,36.7207864 10.5623128,35.2080854 11.612321,34.2826544 C12.6623292,33.3572234 14.3974863,32.8945149 16.8178442,32.8945149 L36.8390873,32.8945149 C40.0069087,32.8945149 42.231469,34.6029772 43.512835,38.0199531 L43.512835,38.180123 L60.4374591,84.522627 Z M32.4611088,44.6937008 L24.7195615,67.224273 L40.2026561,67.224273 L32.4611088,44.6937008 Z M89.5058233,68.5590225 L89.5058233,84.8429669 L97.5143205,84.8429669 C103.173687,84.8429669 107.160099,84.22009 109.473676,82.9743176 C111.787254,81.7285451 112.944025,79.6463566 112.944025,76.7276897 C112.944025,73.7734293 111.840643,71.6734444 109.633846,70.4276719 C107.427049,69.1818994 103.565213,68.5590225 98.0482204,68.5590225 L89.5058233,68.5590225 Z M116.734714,62.6327346 C120.614405,64.0564746 123.461842,66.0051894 125.277111,68.4789376 C127.092379,70.9526857 128,74.1115614 128,77.9556593 C128,81.1946677 127.216955,84.1488838 125.650841,86.8183962 C124.084727,89.4879087 121.84237,91.676876 118.923703,93.385364 C117.215215,94.3819819 115.302093,95.1027395 113.18428,95.5476582 C111.066467,95.9925769 108.06776,96.215033 104.188068,96.215033 L99.7033098,96.215033 L76.3184979,96.215033 C73.9693269,96.215033 72.2875593,95.7523244 71.2731446,94.8268935 C70.2587299,93.9014625 69.7515301,92.3887615 69.7515301,90.288745 C69.7515301,88.4022896 70.2320352,86.9696727 71.1930596,85.9908515 C72.1540841,85.0120303 73.5600062,84.522627 75.4108682,84.522627 L76.3184979,84.522627 L76.3184979,44.6937008 L75.4108682,44.6937008 C73.5600062,44.6937008 72.1540841,44.1953993 71.1930596,43.1987813 C70.2320352,42.2021633 69.7515301,40.7428518 69.7515301,38.8208028 C69.7515301,36.7563799 70.2676281,35.2525771 71.2998396,34.3093494 C72.3320511,33.3661217 74.0049204,32.8945149 76.3184979,32.8945149 L100.877889,32.8945149 C108.388118,32.8945149 114.09189,34.3538264 117.989378,37.2724934 C121.886867,40.1911603 123.835581,44.4623161 123.835581,50.0860889 C123.835581,52.8623819 123.239399,55.3093982 122.047017,57.4272114 C120.854635,59.5450246 119.083885,61.2801816 116.734714,62.6327346 L116.734714,62.6327346 Z M89.5058233,44.3733609 L89.5058233,57.8276363 L96.7134708,57.8276363 C101.091471,57.8276363 104.179161,57.3115383 105.976633,56.2793268 C107.774104,55.2471153 108.672827,53.50306 108.672827,51.0471086 C108.672827,48.7335312 107.863087,47.0428653 106.243583,45.9750604 C104.624078,44.9072554 101.999097,44.3733609 98.3685602,44.3733609 L89.5058233,44.3733609 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/new-button": {
"title": "$:/core/images/new-button",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-new-button tc-image-button\" viewBox=\"0 0 128 128\" width=\"22pt\" height=\"22pt\">\n <g fill-rule=\"evenodd\">\n <path d=\"M56,72 L8.00697327,72 C3.59075293,72 0,68.418278 0,64 C0,59.5907123 3.58484404,56 8.00697327,56 L56,56 L56,8.00697327 C56,3.59075293 59.581722,0 64,0 C68.4092877,0 72,3.58484404 72,8.00697327 L72,56 L119.993027,56 C124.409247,56 128,59.581722 128,64 C128,68.4092877 124.415156,72 119.993027,72 L72,72 L72,119.993027 C72,124.409247 68.418278,128 64,128 C59.5907123,128 56,124.415156 56,119.993027 L56,72 L56,72 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/new-here-button": {
"title": "$:/core/images/new-here-button",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-new-here-button tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n \t<g transform=\"translate(52.233611, 64.389922) rotate(75.000000) translate(-52.233611, -64.389922) translate(-7.734417, 3.702450)\">\n\t <path d=\"M18.9270186,45.959338 L18.9080585,49.6521741 C18.8884833,53.4648378 21.0574548,58.7482162 23.7526408,61.4434022 L78.5671839,116.257945 C81.2617332,118.952495 85.6348701,118.950391 88.3334363,116.251825 L115.863237,88.7220241 C118.555265,86.0299959 118.564544,81.6509578 115.869358,78.9557717 L61.0548144,24.1412286 C58.3602652,21.4466794 53.0787224,19.2788426 49.2595808,19.3006519 L25.9781737,19.4336012 C22.1633003,19.4553862 19.0471195,22.5673232 19.0275223,26.3842526 L18.9871663,34.2443819 C19.0818862,34.255617 19.1779758,34.2665345 19.2754441,34.2771502 C22.6891275,34.6489512 27.0485594,34.2348566 31.513244,33.2285542 C31.7789418,32.8671684 32.075337,32.5211298 32.4024112,32.1940556 C34.8567584,29.7397084 38.3789778,29.0128681 41.4406288,30.0213822 C41.5958829,29.9543375 41.7503946,29.8866669 41.9041198,29.8183808 L42.1110981,30.2733467 C43.1114373,30.6972371 44.0473796,31.3160521 44.8614145,32.1300869 C48.2842088,35.5528813 48.2555691,41.130967 44.7974459,44.5890903 C41.4339531,47.952583 36.0649346,48.0717177 32.6241879,44.9262969 C27.8170558,45.8919233 23.0726921,46.2881596 18.9270186,45.959338 Z\"></path>\n\t <path d=\"M45.4903462,38.8768094 C36.7300141,42.6833154 26.099618,44.7997354 18.1909048,43.9383587 C7.2512621,42.7468685 1.50150083,35.8404432 4.66865776,24.7010202 C7.51507386,14.6896965 15.4908218,6.92103848 24.3842626,4.38423012 C34.1310219,1.60401701 42.4070208,6.15882777 42.4070209,16.3101169 L34.5379395,16.310117 C34.5379394,11.9285862 31.728784,10.3825286 26.5666962,11.8549876 C20.2597508,13.6540114 14.3453742,19.4148216 12.2444303,26.8041943 C10.4963869,32.9523565 12.6250796,35.5092726 19.0530263,36.2093718 C25.5557042,36.9176104 35.0513021,34.9907189 42.7038419,31.5913902 L42.7421786,31.6756595 C44.3874154,31.5384763 47.8846101,37.3706354 45.9274416,38.6772897 L45.9302799,38.6835285 C45.9166992,38.6895612 45.9031139,38.6955897 45.8895238,38.7016142 C45.8389288,38.7327898 45.7849056,38.7611034 45.7273406,38.7863919 C45.6506459,38.8200841 45.571574,38.8501593 45.4903462,38.8768094 Z\"></path>\n </g>\n <rect x=\"96\" y=\"80\" width=\"16\" height=\"48\" rx=\"8\"></rect>\n <rect x=\"80\" y=\"96\" width=\"48\" height=\"16\" rx=\"8\"></rect>\n </g>\n </g>\n</svg>"
},
"$:/core/images/new-image-button": {
"title": "$:/core/images/new-image-button",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-new-image-button tc-image-button\" viewBox=\"0 0 128 128\" width=\"22pt\" height=\"22pt\">\n <g fill-rule=\"evenodd\">\n <path d=\"M81.3619177,73.6270062 L97.1875317,46.2162388 C97.91364,44.9585822 97.4824378,43.3533085 96.2260476,42.6279312 L46.2162388,13.7547547 C44.9585822,13.0286463 43.3533085,13.4598485 42.6279312,14.7162388 L30.0575956,36.4886988 L40.0978909,31.2276186 C43.1404959,29.6333041 46.8692155,31.3421319 47.6479264,34.6877101 L51.2545483,52.3903732 L61.1353556,53.2399953 C63.2899974,53.4346096 65.1046382,54.9309951 65.706105,57.0091178 C65.7395572,57.1246982 65.8069154,57.3539875 65.9047035,57.6813669 C66.0696435,58.2335608 66.2581528,58.852952 66.4667073,59.5238092 C67.0618822,61.4383079 67.6960725,63.3742727 68.3393254,65.2021174 C68.5462918,65.7902259 68.7511789,66.3583016 68.953259,66.9034738 C69.5777086,68.5881157 70.1617856,70.0172008 70.6783305,71.110045 C70.9334784,71.6498566 71.1627732,72.0871602 71.4035746,72.5373068 C71.6178999,72.7492946 71.9508843,72.9623307 72.4151452,73.1586945 C73.5561502,73.6412938 75.1990755,73.899146 77.0720271,73.9171651 C77.9355886,73.9254732 78.7819239,73.8832103 79.5638842,73.8072782 C80.0123946,73.7637257 80.3172916,73.7224469 80.4352582,73.7027375 C80.7503629,73.6500912 81.0598053,73.6256267 81.3619177,73.6270062 L81.3619177,73.6270062 L81.3619177,73.6270062 L81.3619177,73.6270062 Z M37.4707881,2.64867269 C38.9217993,0.135447653 42.1388058,-0.723707984 44.6486727,0.725364314 L108.293614,37.4707881 C110.806839,38.9217993 111.665994,42.1388058 110.216922,44.6486727 L73.4714982,108.293614 C72.0204871,110.806839 68.8034805,111.665994 66.2936136,110.216922 L2.64867269,73.4714982 C0.135447653,72.0204871 -0.723707984,68.8034805 0.725364314,66.2936136 L37.4707881,2.64867269 L37.4707881,2.64867269 L37.4707881,2.64867269 L37.4707881,2.64867269 Z M80.3080975,53.1397764 C82.8191338,54.5895239 86.0299834,53.7291793 87.4797308,51.218143 C88.9294783,48.7071068 88.0691338,45.4962571 85.5580975,44.0465097 C83.0470612,42.5967622 79.8362116,43.4571068 78.3864641,45.968143 C76.9367166,48.4791793 77.7970612,51.6900289 80.3080975,53.1397764 L80.3080975,53.1397764 L80.3080975,53.1397764 L80.3080975,53.1397764 Z M96,112 L88.0070969,112 C83.5881712,112 80,108.418278 80,104 C80,99.5907123 83.5848994,96 88.0070969,96 L96,96 L96,88.0070969 C96,83.5881712 99.581722,80 104,80 C108.409288,80 112,83.5848994 112,88.0070969 L112,96 L119.992903,96 C124.411829,96 128,99.581722 128,104 C128,108.409288 124.415101,112 119.992903,112 L112,112 L112,119.992903 C112,124.411829 108.418278,128 104,128 C99.5907123,128 96,124.415101 96,119.992903 L96,112 L96,112 Z M33.3471097,51.7910932 C40.7754579,59.7394511 42.3564368,62.4818351 40.7958321,65.1848818 C39.2352273,67.8879286 26.9581062,62.8571718 24.7019652,66.7649227 C22.4458242,70.6726735 23.7947046,70.0228006 22.2648667,72.6725575 L41.9944593,84.0634431 C41.9944593,84.0634431 36.3904568,75.8079231 37.7602356,73.4353966 C40.2754811,69.0788636 46.5298923,72.1787882 48.1248275,69.4162793 C50.538989,65.234829 43.0222016,59.7770885 33.3471097,51.7910932 L33.3471097,51.7910932 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/new-journal-button": {
"title": "$:/core/images/new-journal-button",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-new-journal-button tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M102.545455,112.818182 L102.545455,124.636364 L102.545455,124.636364 L102.545455,124.636364 C102.545455,125.941761 103.630828,127 104.969697,127 L111.030303,127 C112.369172,127 113.454545,125.941761 113.454545,124.636364 L113.454545,112.818182 L125.575758,112.818182 C126.914626,112.818182 128,111.759982 128,110.454545 L128,104.545455 C128,103.240018 126.914626,102.181818 125.575758,102.181818 L113.454545,102.181818 L113.454545,90.3636364 C113.454545,89.0582 112.369172,88 111.030303,88 L104.969697,88 L104.969697,88 C103.630828,88 102.545455,89.0582 102.545455,90.3636364 L102.545455,102.181818 L90.4242424,102.181818 L90.4242424,102.181818 C89.0853705,102.181818 88,103.240018 88,104.545455 L88,110.454545 L88,110.454545 L88,110.454545 C88,111.759982 89.0853705,112.818182 90.4242424,112.818182 L102.545455,112.818182 Z\"></path>\n <g transform=\"translate(59.816987, 64.316987) rotate(30.000000) translate(-59.816987, -64.316987) translate(20.316987, 12.816987)\">\n <g transform=\"translate(0.000000, 0.000000)\">\n <path d=\"M9.99631148,0 C4.4755011,0 -2.27373675e-13,4.48070044 -2.27373675e-13,9.99759461 L-2.27373675e-13,91.6128884 C-2.27373675e-13,97.1344074 4.46966773,101.610483 9.99631148,101.610483 L68.9318917,101.610483 C74.4527021,101.610483 78.9282032,97.1297826 78.9282032,91.6128884 L78.9282032,9.99759461 C78.9282032,4.47607557 74.4585355,0 68.9318917,0 L9.99631148,0 Z M20.8885263,26 C24.2022348,26 26.8885263,23.3137085 26.8885263,20 C26.8885263,16.6862915 24.2022348,14 20.8885263,14 C17.5748178,14 14.8885263,16.6862915 14.8885263,20 C14.8885263,23.3137085 17.5748178,26 20.8885263,26 Z M57.3033321,25.6783342 C60.6170406,25.6783342 63.3033321,22.9920427 63.3033321,19.6783342 C63.3033321,16.3646258 60.6170406,13.6783342 57.3033321,13.6783342 C53.9896236,13.6783342 51.3033321,16.3646258 51.3033321,19.6783342 C51.3033321,22.9920427 53.9896236,25.6783342 57.3033321,25.6783342 Z\"></path>\n <text font-family=\"Helvetica\" font-size=\"47.1724138\" font-weight=\"bold\" fill=\"#FFFFFF\">\n <tspan x=\"42\" y=\"77.4847912\" text-anchor=\"middle\"><<now \"DD\">></tspan>\n </text>\n </g>\n </g>\n </g>\n</svg>"
},
"$:/core/images/opacity": {
"title": "$:/core/images/opacity",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-opacity tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M102.361773,65 C101.833691,67.051742 101.183534,69.0544767 100.419508,71 L82.5835324,71 C83.7602504,69.1098924 84.7666304,67.1027366 85.581205,65 L102.361773,65 Z M102.834311,63 C103.256674,61.0388326 103.568427,59.0365486 103.762717,57 L87.6555706,57 C87.3692052,59.0609452 86.9083652,61.0660782 86.2884493,63 L102.834311,63 Z M99.5852583,73 C98.6682925,75.0747721 97.6196148,77.0783056 96.4498253,79 L75.8124196,79 C77.8387053,77.2115633 79.6621163,75.1985844 81.2437158,73 L99.5852583,73 Z M95.1689122,81 C93.7449202,83.1155572 92.1695234,85.1207336 90.458251,87 L60.4614747,87 C65.1836162,85.86248 69.5430327,83.794147 73.3347255,81 L95.1689122,81 Z M87.6555706,47 L103.762717,47 C101.246684,20.6269305 79.0321807,0 52,0 C23.281193,0 0,23.281193 0,52 C0,77.2277755 17.9651296,98.2595701 41.8000051,103 L62.1999949,103 C67.8794003,101.870444 73.2255333,99.8158975 78.074754,97 L39,97 L39,95 L81.2493857,95 C83.8589242,93.2215015 86.2981855,91.2116653 88.5376609,89 L39,89 L39,87 L43.5385253,87 C27.7389671,83.1940333 16,68.967908 16,52 C16,32.117749 32.117749,16 52,16 C70.1856127,16 85.2217929,29.4843233 87.6555706,47 Z M87.8767787,49 L103.914907,49 C103.971379,49.9928025 104,50.9930589 104,52 C104,53.0069411 103.971379,54.0071975 103.914907,55 L87.8767787,55 C87.958386,54.0107999 88,53.0102597 88,52 C88,50.9897403 87.958386,49.9892001 87.8767787,49 Z\"></path>\n <path d=\"M76,128 C104.718807,128 128,104.718807 128,76 C128,47.281193 104.718807,24 76,24 C47.281193,24 24,47.281193 24,76 C24,104.718807 47.281193,128 76,128 L76,128 Z M76,112 C95.882251,112 112,95.882251 112,76 C112,56.117749 95.882251,40 76,40 C56.117749,40 40,56.117749 40,76 C40,95.882251 56.117749,112 76,112 L76,112 Z\"></path>\n <path d=\"M37,58 L90,58 L90,62 L37,62 L37,58 L37,58 Z M40,50 L93,50 L93,54 L40,54 L40,50 L40,50 Z M40,42 L93,42 L93,46 L40,46 L40,42 L40,42 Z M32,66 L85,66 L85,70 L32,70 L32,66 L32,66 Z M30,74 L83,74 L83,78 L30,78 L30,74 L30,74 Z M27,82 L80,82 L80,86 L27,86 L27,82 L27,82 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/open-window": {
"title": "$:/core/images/open-window",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-open-window tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M16,112 L104.993898,112 C108.863261,112 112,115.590712 112,120 C112,124.418278 108.858091,128 104.993898,128 L7.00610161,128 C3.13673853,128 0,124.409288 0,120 C0,119.998364 4.30952878e-07,119.996727 1.29273572e-06,119.995091 C4.89579306e-07,119.993456 0,119.99182 0,119.990183 L0,24.0098166 C0,19.586117 3.59071231,16 8,16 C12.418278,16 16,19.5838751 16,24.0098166 L16,112 Z\"></path>\n <path d=\"M96,43.1959595 L96,56 C96,60.418278 99.581722,64 104,64 C108.418278,64 112,60.418278 112,56 L112,24 C112,19.5907123 108.415101,16 103.992903,16 L72.0070969,16 C67.5881712,16 64,19.581722 64,24 C64,28.4092877 67.5848994,32 72.0070969,32 L84.5685425,32 L48.2698369,68.2987056 C45.1421332,71.4264093 45.1434327,76.4904296 48.267627,79.614624 C51.3854642,82.7324612 56.4581306,82.7378289 59.5835454,79.6124141 L96,43.1959595 Z M32,7.9992458 C32,3.58138434 35.5881049,0 39.9992458,0 L120.000754,0 C124.418616,0 128,3.5881049 128,7.9992458 L128,88.0007542 C128,92.4186157 124.411895,96 120.000754,96 L39.9992458,96 C35.5813843,96 32,92.4118951 32,88.0007542 L32,7.9992458 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/options-button": {
"title": "$:/core/images/options-button",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-options-button tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M110.48779,76.0002544 C109.354214,80.4045063 107.611262,84.5641217 105.354171,88.3838625 L105.354171,88.3838625 L112.07833,95.1080219 C115.20107,98.2307613 115.210098,103.299824 112.089164,106.420759 L106.420504,112.089418 C103.301049,115.208874 98.2346851,115.205502 95.1077675,112.078585 L88.3836082,105.354425 C84.5638673,107.611516 80.4042519,109.354468 76,110.488045 L76,110.488045 L76,119.993281 C76,124.409501 72.4220153,128.000254 68.0083475,128.000254 L59.9916525,128.000254 C55.5800761,128.000254 52,124.41541 52,119.993281 L52,110.488045 C47.5957481,109.354468 43.4361327,107.611516 39.6163918,105.354425 L32.8922325,112.078585 C29.7694931,115.201324 24.7004301,115.210353 21.5794957,112.089418 L15.9108363,106.420759 C12.7913807,103.301303 12.7947522,98.2349395 15.9216697,95.1080219 L22.6458291,88.3838625 C20.3887383,84.5641217 18.6457859,80.4045063 17.5122098,76.0002544 L8.00697327,76.0002544 C3.59075293,76.0002544 2.19088375e-16,72.4222697 4.89347582e-16,68.0086019 L9.80228577e-16,59.9919069 C1.25035972e-15,55.5803305 3.58484404,52.0002544 8.00697327,52.0002544 L17.5122098,52.0002544 C18.6457859,47.5960025 20.3887383,43.4363871 22.6458291,39.6166462 L15.9216697,32.8924868 C12.7989304,29.7697475 12.7899019,24.7006845 15.9108363,21.5797501 L21.5794957,15.9110907 C24.6989513,12.7916351 29.7653149,12.7950065 32.8922325,15.9219241 L39.6163918,22.6460835 C43.4361327,20.3889927 47.5957481,18.6460403 52,17.5124642 L52,8.00722764 C52,3.5910073 55.5779847,0.000254375069 59.9916525,0.000254375069 L68.0083475,0.000254375069 C72.4199239,0.000254375069 76,3.58509841 76,8.00722764 L76,17.5124642 C80.4042519,18.6460403 84.5638673,20.3889927 88.3836082,22.6460835 L95.1077675,15.9219241 C98.2305069,12.7991848 103.29957,12.7901562 106.420504,15.9110907 L112.089164,21.5797501 C115.208619,24.6992057 115.205248,29.7655693 112.07833,32.8924868 L105.354171,39.6166462 L105.354171,39.6166462 C107.611262,43.4363871 109.354214,47.5960025 110.48779,52.0002544 L119.993027,52.0002544 C124.409247,52.0002544 128,55.5782391 128,59.9919069 L128,68.0086019 C128,72.4201783 124.415156,76.0002544 119.993027,76.0002544 L110.48779,76.0002544 L110.48779,76.0002544 Z M64,96.0002544 C81.673112,96.0002544 96,81.6733664 96,64.0002544 C96,46.3271424 81.673112,32.0002544 64,32.0002544 C46.326888,32.0002544 32,46.3271424 32,64.0002544 C32,81.6733664 46.326888,96.0002544 64,96.0002544 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/paint": {
"title": "$:/core/images/paint",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-paint tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M83.5265806,76.1907935 C90.430962,69.2864121 91.8921169,59.0000433 87.9100453,50.6642209 L125.812763,12.7615036 C128.732035,9.84223095 128.72611,5.10322984 125.812796,2.18991592 C122.893542,-0.729338085 118.161775,-0.730617045 115.241209,2.18994966 L77.3384914,40.092667 C69.002669,36.1105954 58.7163002,37.5717503 51.8119188,44.4761317 L83.5265806,76.1907935 L83.5265806,76.1907935 L83.5265806,76.1907935 L83.5265806,76.1907935 Z M80.8836921,78.8336819 L49.1690303,47.1190201 C49.1690303,47.1190201 8.50573364,81.242543 0,80.2820711 C0,80.2820711 3.78222974,85.8744423 6.82737483,88.320684 C20.8514801,82.630792 44.1526049,63.720771 44.1526049,63.720771 L44.8144806,64.3803375 C44.8144806,64.3803375 19.450356,90.2231043 9.18040433,92.0477601 C10.4017154,93.4877138 13.5343883,96.1014812 15.4269991,97.8235871 C20.8439164,96.3356979 50.1595367,69.253789 50.1595367,69.253789 L50.8214124,69.9133555 L18.4136144,100.936036 L23.6993903,106.221812 L56.1060358,75.2002881 L56.7679115,75.8598546 C56.7679115,75.8598546 28.9040131,106.396168 28.0841366,108.291555 C28.0841366,108.291555 34.1159238,115.144621 35.6529617,116.115796 C36.3545333,113.280171 63.5365402,82.6307925 63.5365402,82.6307925 L64.1984159,83.290359 C64.1984159,83.290359 43.6013016,107.04575 39.2343772,120.022559 C42.443736,123.571575 46.7339155,125.159692 50.1595362,126.321151 C47.9699978,114.504469 80.8836921,78.8336819 80.8836921,78.8336819 L80.8836921,78.8336819 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/palette": {
"title": "$:/core/images/palette",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-palette tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M80.2470434,39.1821571 C75.0645698,38.2680897 69.6261555,37.7814854 64.0193999,37.7814854 C28.6624616,37.7814854 0,57.1324214 0,81.0030106 C0,90.644534 4.67604329,99.5487133 12.5805659,106.738252 C23.5031767,91.1899067 26.3405471,72.3946229 36.8885698,63.5622337 C52.0716764,50.8486559 63.4268694,55.7343343 63.4268694,55.7343343 L80.2470434,39.1821571 Z M106.781666,48.8370714 C119.830962,56.749628 128.0388,68.229191 128.0388,81.0030106 C128.0388,90.3534932 128.557501,98.4142085 116.165191,106.082518 C105.367708,112.763955 112.341384,99.546808 104.321443,95.1851533 C96.3015017,90.8234987 84.3749007,96.492742 86.1084305,103.091059 C89.3087234,115.272303 105.529892,114.54645 92.4224435,119.748569 C79.3149955,124.950687 74.2201582,124.224536 64.0193999,124.224536 C56.1979176,124.224536 48.7040365,123.277578 41.7755684,121.544216 C51.620343,117.347916 69.6563669,109.006202 75.129737,102.088562 C82.7876655,92.4099199 87.3713218,80.0000002 83.3235694,72.4837191 C83.1303943,72.1250117 94.5392656,60.81569 106.781666,48.8370714 Z M1.13430476,123.866563 C0.914084026,123.867944 0.693884185,123.868637 0.473712455,123.868637 C33.9526848,108.928928 22.6351223,59.642592 59.2924543,59.6425917 C59.6085574,61.0606542 59.9358353,62.5865065 60.3541977,64.1372318 C34.4465025,59.9707319 36.7873124,112.168427 1.13429588,123.866563 L1.13430476,123.866563 Z M1.84669213,123.859694 C40.7185279,123.354338 79.9985412,101.513051 79.9985401,79.0466836 C70.7284906,79.0466835 65.9257264,75.5670082 63.1833375,71.1051511 C46.585768,64.1019718 32.81846,116.819636 1.84665952,123.859695 L1.84669213,123.859694 Z M67.1980193,59.8524981 C62.748213,63.9666823 72.0838429,76.2846822 78.5155805,71.1700593 C89.8331416,59.8524993 112.468264,37.2173758 123.785825,25.8998146 C135.103386,14.5822535 123.785825,3.26469247 112.468264,14.5822535 C101.150703,25.8998144 78.9500931,48.9868127 67.1980193,59.8524981 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/permalink-button": {
"title": "$:/core/images/permalink-button",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-permalink-button tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M80.4834582,48 L73.0956761,80 L73.0956761,80 L47.5165418,80 L54.9043239,48 L80.4834582,48 Z M84.1773493,32 L89.8007299,7.64246248 C90.7941633,3.33942958 95.0918297,0.64641956 99.3968675,1.64031585 C103.693145,2.63218977 106.385414,6.93288901 105.390651,11.2416793 L100.598215,32 L104.000754,32 C108.411895,32 112,35.581722 112,40 C112,44.4092877 108.418616,48 104.000754,48 L96.9043239,48 L89.5165418,80 L104.000754,80 C108.411895,80 112,83.581722 112,88 C112,92.4092877 108.418616,96 104.000754,96 L85.8226507,96 L80.1992701,120.357538 C79.2058367,124.66057 74.9081703,127.35358 70.6031325,126.359684 C66.3068546,125.36781 63.6145865,121.067111 64.6093491,116.758321 L69.401785,96 L43.8226507,96 L38.1992701,120.357538 C37.2058367,124.66057 32.9081703,127.35358 28.6031325,126.359684 C24.3068546,125.36781 21.6145865,121.067111 22.6093491,116.758321 L27.401785,96 L23.9992458,96 C19.5881049,96 16,92.418278 16,88 C16,83.5907123 19.5813843,80 23.9992458,80 L31.0956761,80 L38.4834582,48 L23.9992458,48 C19.5881049,48 16,44.418278 16,40 C16,35.5907123 19.5813843,32 23.9992458,32 L42.1773493,32 L47.8007299,7.64246248 C48.7941633,3.33942958 53.0918297,0.64641956 57.3968675,1.64031585 C61.6931454,2.63218977 64.3854135,6.93288901 63.3906509,11.2416793 L58.598215,32 L84.1773493,32 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/permaview-button": {
"title": "$:/core/images/permaview-button",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-permaview-button tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M81.4834582,48 L79.6365127,56 L79.6365127,56 L74.0573784,56 L75.9043239,48 L81.4834582,48 Z M85.1773493,32 L90.8007299,7.64246248 C91.7941633,3.33942958 96.0918297,0.64641956 100.396867,1.64031585 C104.693145,2.63218977 107.385414,6.93288901 106.390651,11.2416793 L101.598215,32 L104.000754,32 C108.411895,32 112,35.581722 112,40 C112,44.4092877 108.418616,48 104.000754,48 L97.9043239,48 L96.0573784,56 L104.000754,56 C108.411895,56 112,59.581722 112,64 C112,68.4092877 108.418616,72 104.000754,72 L92.3634873,72 L90.5165418,80 L104.000754,80 C108.411895,80 112,83.581722 112,88 C112,92.4092877 108.418616,96 104.000754,96 L86.8226507,96 L81.1992701,120.357538 C80.2058367,124.66057 75.9081703,127.35358 71.6031325,126.359684 C67.3068546,125.36781 64.6145865,121.067111 65.6093491,116.758321 L70.401785,96 L64.8226507,96 L59.1992701,120.357538 C58.2058367,124.66057 53.9081703,127.35358 49.6031325,126.359684 C45.3068546,125.36781 42.6145865,121.067111 43.6093491,116.758321 L48.401785,96 L42.8226507,96 L37.1992701,120.357538 C36.2058367,124.66057 31.9081703,127.35358 27.6031325,126.359684 C23.3068546,125.36781 20.6145865,121.067111 21.6093491,116.758321 L26.401785,96 L23.9992458,96 C19.5881049,96 16,92.418278 16,88 C16,83.5907123 19.5813843,80 23.9992458,80 L30.0956761,80 L31.9426216,72 L23.9992458,72 C19.5881049,72 16,68.418278 16,64 C16,59.5907123 19.5813843,56 23.9992458,56 L35.6365127,56 L37.4834582,48 L23.9992458,48 C19.5881049,48 16,44.418278 16,40 C16,35.5907123 19.5813843,32 23.9992458,32 L41.1773493,32 L46.8007299,7.64246248 C47.7941633,3.33942958 52.0918297,0.64641956 56.3968675,1.64031585 C60.6931454,2.63218977 63.3854135,6.93288901 62.3906509,11.2416793 L57.598215,32 L63.1773493,32 L68.8007299,7.64246248 C69.7941633,3.33942958 74.0918297,0.64641956 78.3968675,1.64031585 C82.6931454,2.63218977 85.3854135,6.93288901 84.3906509,11.2416793 L79.598215,32 L85.1773493,32 Z M53.9043239,48 L52.0573784,56 L57.6365127,56 L59.4834582,48 L53.9043239,48 Z M75.9426216,72 L74.0956761,80 L74.0956761,80 L68.5165418,80 L70.3634873,72 L75.9426216,72 L75.9426216,72 Z M48.3634873,72 L46.5165418,80 L52.0956761,80 L53.9426216,72 L48.3634873,72 L48.3634873,72 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/picture": {
"title": "$:/core/images/picture",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-picture tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M112,68.2332211 L112,20.0027785 C112,17.7898769 110.207895,16 107.997221,16 L20.0027785,16 C17.7898769,16 16,17.792105 16,20.0027785 L16,58.312373 L25.2413115,43.7197989 C28.041793,39.297674 34.2643908,38.7118128 37.8410347,42.5335275 L56.0882845,63.1470817 L69.7748997,56.7400579 C72.766567,55.3552503 76.3013751,55.9473836 78.678437,58.2315339 C78.8106437,58.3585731 79.0742301,58.609836 79.4527088,58.9673596 C80.0910923,59.570398 80.8117772,60.2441563 81.598127,60.9705595 C83.8422198,63.043576 86.1541548,65.1151944 88.3956721,67.0372264 C89.1168795,67.6556396 89.8200801,68.2492007 90.5021258,68.8146755 C92.6097224,70.5620551 94.4693308,72.0029474 95.9836366,73.0515697 C96.7316295,73.5695379 97.3674038,73.9719282 98.0281481,74.3824999 C98.4724987,74.4989557 99.0742374,74.5263881 99.8365134,74.4317984 C101.709944,74.1993272 104.074502,73.2878514 106.559886,71.8846196 C107.705822,71.2376318 108.790494,70.5370325 109.764561,69.8410487 C110.323259,69.4418522 110.694168,69.1550757 110.834827,69.0391868 C111.210545,68.7296319 111.600264,68.4615815 112,68.2332211 L112,68.2332211 Z M0,8.00697327 C0,3.58484404 3.59075293,0 8.00697327,0 L119.993027,0 C124.415156,0 128,3.59075293 128,8.00697327 L128,119.993027 C128,124.415156 124.409247,128 119.993027,128 L8.00697327,128 C3.58484404,128 0,124.409247 0,119.993027 L0,8.00697327 L0,8.00697327 Z M95,42 C99.418278,42 103,38.418278 103,34 C103,29.581722 99.418278,26 95,26 C90.581722,26 87,29.581722 87,34 C87,38.418278 90.581722,42 95,42 L95,42 Z M32,76 C47.8587691,80.8294182 52.0345556,83.2438712 52.0345556,88 C52.0345556,92.7561288 32,95.4712486 32,102.347107 C32,109.222965 33.2849191,107.337637 33.2849191,112 L67.999999,112 C67.999999,112 54.3147136,105.375255 54.3147136,101.200691 C54.3147136,93.535181 64.9302432,92.860755 64.9302432,88 C64.9302432,80.6425555 50.8523779,79.167282 32,76 L32,76 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/plugin-generic-language": {
"title": "$:/core/images/plugin-generic-language",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M61.2072232,68.1369825 C56.8829239,70.9319564 54.2082892,74.793177 54.2082892,79.0581634 C54.2082892,86.9638335 63.3980995,93.4821994 75.2498076,94.3940006 C77.412197,98.2964184 83.8475284,101.178858 91.5684735,101.403106 C86.4420125,100.27851 82.4506393,97.6624107 80.9477167,94.3948272 C92.8046245,93.4861461 102,86.9662269 102,79.0581634 C102,70.5281905 91.3014611,63.6132813 78.1041446,63.6132813 C71.5054863,63.6132813 65.5315225,65.3420086 61.2072232,68.1369825 Z M74.001066,53.9793443 C69.6767667,56.7743182 63.7028029,58.5030456 57.1041446,58.5030456 C54.4851745,58.5030456 51.9646095,58.2307276 49.6065315,57.7275105 C46.2945155,59.9778212 41.2235699,61.4171743 35.5395922,61.4171743 C35.4545771,61.4171743 35.3696991,61.4168523 35.2849622,61.4162104 C39.404008,60.5235193 42.7961717,58.6691298 44.7630507,56.286533 C37.8379411,53.5817651 33.2082892,48.669413 33.2082892,43.0581634 C33.2082892,34.5281905 43.9068281,27.6132812 57.1041446,27.6132812 C70.3014611,27.6132812 81,34.5281905 81,43.0581634 C81,47.3231498 78.3253653,51.1843704 74.001066,53.9793443 Z M64,0 L118.5596,32 L118.5596,96 L64,128 L9.44039956,96 L9.44039956,32 L64,0 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/plugin-generic-plugin": {
"title": "$:/core/images/plugin-generic-plugin",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M40.3972881,76.4456988 L40.3972881,95.3404069 L54.5170166,95.3404069 L54.5170166,95.3404069 C54.5165526,95.3385183 54.516089,95.3366295 54.515626,95.3347404 C54.6093153,95.3385061 54.7034848,95.3404069 54.7980982,95.3404069 C58.6157051,95.3404069 61.710487,92.245625 61.710487,88.4280181 C61.710487,86.6197822 61.01617,84.9737128 59.8795929,83.7418666 L59.8795929,83.7418666 C59.8949905,83.7341665 59.9104102,83.7265043 59.925852,83.7188798 C58.8840576,82.5086663 58.2542926,80.9336277 58.2542926,79.2114996 C58.2542926,75.3938927 61.3490745,72.2991108 65.1666814,72.2991108 C68.9842884,72.2991108 72.0790703,75.3938927 72.0790703,79.2114996 C72.0790703,81.1954221 71.2432806,82.9841354 69.9045961,84.2447446 L69.9045961,84.2447446 C69.9333407,84.2629251 69.9619885,84.281245 69.9905383,84.2997032 L69.9905383,84.2997032 C69.1314315,85.4516923 68.6228758,86.8804654 68.6228758,88.4280181 C68.6228758,91.8584969 71.1218232,94.7053153 74.3986526,95.2474079 C74.3913315,95.2784624 74.3838688,95.3094624 74.3762652,95.3404069 L95.6963988,95.3404069 L95.6963988,75.5678578 L95.6963988,75.5678578 C95.6466539,75.5808558 95.5967614,75.5934886 95.5467242,75.6057531 C95.5504899,75.5120637 95.5523907,75.4178943 95.5523907,75.3232809 C95.5523907,71.505674 92.4576088,68.4108921 88.6400019,68.4108921 C86.831766,68.4108921 85.1856966,69.105209 83.9538504,70.2417862 L83.9538504,70.2417862 C83.9461503,70.2263886 83.938488,70.2109688 83.9308636,70.1955271 C82.7206501,71.2373215 81.1456115,71.8670865 79.4234834,71.8670865 C75.6058765,71.8670865 72.5110946,68.7723046 72.5110946,64.9546976 C72.5110946,61.1370907 75.6058765,58.0423088 79.4234834,58.0423088 C81.4074059,58.0423088 83.1961192,58.8780985 84.4567284,60.2167829 L84.4567284,60.2167829 C84.4749089,60.1880383 84.4932288,60.1593906 84.511687,60.1308407 L84.511687,60.1308407 C85.6636761,60.9899475 87.0924492,61.4985032 88.6400019,61.4985032 C92.0704807,61.4985032 94.9172991,58.9995558 95.4593917,55.7227265 C95.538755,55.7414363 95.6177614,55.761071 95.6963988,55.7816184 L95.6963988,40.0412962 L74.3762652,40.0412962 L74.3762652,40.0412962 C74.3838688,40.0103516 74.3913315,39.9793517 74.3986526,39.9482971 L74.3986526,39.9482971 C71.1218232,39.4062046 68.6228758,36.5593862 68.6228758,33.1289073 C68.6228758,31.5813547 69.1314315,30.1525815 69.9905383,29.0005925 C69.9619885,28.9821342 69.9333407,28.9638143 69.9045961,28.9456339 C71.2432806,27.6850247 72.0790703,25.8963113 72.0790703,23.9123888 C72.0790703,20.0947819 68.9842884,17 65.1666814,17 C61.3490745,17 58.2542926,20.0947819 58.2542926,23.9123888 C58.2542926,25.6345169 58.8840576,27.2095556 59.925852,28.419769 L59.925852,28.419769 C59.9104102,28.4273935 59.8949905,28.4350558 59.8795929,28.4427558 C61.01617,29.674602 61.710487,31.3206715 61.710487,33.1289073 C61.710487,36.9465143 58.6157051,40.0412962 54.7980982,40.0412962 C54.7034848,40.0412962 54.6093153,40.0393953 54.515626,40.0356296 L54.515626,40.0356296 C54.516089,40.0375187 54.5165526,40.0394075 54.5170166,40.0412962 L40.3972881,40.0412962 L40.3972881,52.887664 L40.3972881,52.887664 C40.4916889,53.3430132 40.5412962,53.8147625 40.5412962,54.2980982 C40.5412962,58.1157051 37.4465143,61.210487 33.6289073,61.210487 C32.0813547,61.210487 30.6525815,60.7019313 29.5005925,59.8428245 C29.4821342,59.8713744 29.4638143,59.9000221 29.4456339,59.9287667 C28.1850247,58.5900823 26.3963113,57.7542926 24.4123888,57.7542926 C20.5947819,57.7542926 17.5,60.8490745 17.5,64.6666814 C17.5,68.4842884 20.5947819,71.5790703 24.4123888,71.5790703 C26.134517,71.5790703 27.7095556,70.9493053 28.919769,69.9075109 L28.919769,69.9075109 C28.9273935,69.9229526 28.9350558,69.9383724 28.9427558,69.95377 C30.174602,68.8171928 31.8206715,68.1228758 33.6289073,68.1228758 C37.4465143,68.1228758 40.5412962,71.2176578 40.5412962,75.0352647 C40.5412962,75.5186004 40.4916889,75.9903496 40.3972881,76.4456988 Z M64,0 L118.5596,32 L118.5596,96 L64,128 L9.44039956,96 L9.44039956,32 L64,0 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/plugin-generic-theme": {
"title": "$:/core/images/plugin-generic-theme",
"tags": "$:/tags/Image",
"text": "<svg width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M29.4078519,91.4716406 L51.4693474,69.4101451 L51.4646675,69.4054652 C50.5969502,68.5377479 50.5929779,67.1348725 51.4693474,66.2585029 C52.3396494,65.3882009 53.7499654,65.3874786 54.6163097,66.2538229 L64.0805963,75.7181095 C64.9483136,76.5858268 64.9522859,77.9887022 64.0759163,78.8650718 C63.2056143,79.7353737 61.7952984,79.736096 60.9289541,78.8697517 L60.9242741,78.8650718 L60.9242741,78.8650718 L38.8627786,100.926567 C36.2518727,103.537473 32.0187578,103.537473 29.4078519,100.926567 C26.796946,98.3156614 26.796946,94.0825465 29.4078519,91.4716406 Z M60.8017407,66.3810363 C58.3659178,63.6765806 56.3370667,61.2899536 54.9851735,59.5123615 C48.1295381,50.4979488 44.671561,55.2444054 40.7586738,59.5123614 C36.8457866,63.7803174 41.789473,67.2384487 38.0759896,70.2532832 C34.3625062,73.2681177 34.5917646,74.3131575 28.3243876,68.7977024 C22.0570105,63.2822473 21.6235306,61.7636888 24.5005999,58.6166112 C27.3776691,55.4695337 29.7823103,60.4247912 35.6595047,54.8320442 C41.5366991,49.2392972 36.5996215,44.2825646 36.5996215,44.2825646 C36.5996215,44.2825646 48.8365511,19.267683 65.1880231,21.1152173 C81.5394952,22.9627517 59.0022276,18.7228947 53.3962199,38.3410355 C50.9960082,46.7405407 53.8429162,44.7613399 58.3941742,48.3090467 C59.7875202,49.3951602 64.4244828,52.7100463 70.1884353,56.9943417 L90.8648751,36.3179019 L92.4795866,31.5515482 L100.319802,26.8629752 L103.471444,30.0146174 L98.782871,37.8548326 L94.0165173,39.4695441 L73.7934912,59.6925702 C86.4558549,69.2403631 102.104532,81.8392557 102.104532,86.4016913 C102.104533,93.6189834 99.0337832,97.9277545 92.5695848,95.5655717 C87.8765989,93.8506351 73.8015497,80.3744087 63.8173444,69.668717 L60.9242741,72.5617873 L57.7726319,69.4101451 L60.8017407,66.3810363 L60.8017407,66.3810363 Z M63.9533761,1.42108547e-13 L118.512977,32 L118.512977,96 L63.9533761,128 L9.39377563,96 L9.39377563,32 L63.9533761,1.42108547e-13 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/preview-closed": {
"title": "$:/core/images/preview-closed",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-preview-closed tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M0.0881363238,64 C-0.210292223,65.8846266 0.249135869,67.8634737 1.4664206,69.4579969 C16.2465319,88.8184886 39.1692554,100.414336 64,100.414336 C88.8307446,100.414336 111.753468,88.8184886 126.533579,69.4579969 C127.750864,67.8634737 128.210292,65.8846266 127.911864,64 C110.582357,78.4158332 88.3036732,87.0858436 64,87.0858436 C39.6963268,87.0858436 17.4176431,78.4158332 0.0881363238,64 Z\"></path>\n <rect x=\"62\" y=\"96\" width=\"4\" height=\"16\" rx=\"4\"></rect>\n <rect transform=\"translate(80.000000, 101.000000) rotate(-5.000000) translate(-80.000000, -101.000000) \" x=\"78\" y=\"93\" width=\"4\" height=\"16\" rx=\"4\"></rect>\n <rect transform=\"translate(48.000000, 101.000000) rotate(-355.000000) translate(-48.000000, -101.000000) \" x=\"46\" y=\"93\" width=\"4\" height=\"16\" rx=\"4\"></rect>\n <rect transform=\"translate(32.000000, 96.000000) rotate(-350.000000) translate(-32.000000, -96.000000) \" x=\"30\" y=\"88\" width=\"4\" height=\"16\" rx=\"4\"></rect>\n <rect transform=\"translate(96.000000, 96.000000) rotate(-10.000000) translate(-96.000000, -96.000000) \" x=\"94\" y=\"88\" width=\"4\" height=\"16\" rx=\"4\"></rect>\n <rect transform=\"translate(112.000000, 88.000000) rotate(-20.000000) translate(-112.000000, -88.000000) \" x=\"110\" y=\"80\" width=\"4\" height=\"16\" rx=\"4\"></rect>\n <rect transform=\"translate(16.000000, 88.000000) rotate(-340.000000) translate(-16.000000, -88.000000) \" x=\"14\" y=\"80\" width=\"4\" height=\"16\" rx=\"4\"></rect>\n </g>\n</svg>"
},
"$:/core/images/preview-open": {
"title": "$:/core/images/preview-open",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-preview-open tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M64.1099282,99.5876785 C39.2791836,99.5876785 16.3564602,87.9918313 1.57634884,68.6313396 C-0.378878622,66.070184 -0.378878622,62.5174945 1.57634884,59.9563389 C16.3564602,40.5958472 39.2791836,29 64.1099282,29 C88.9406729,29 111.863396,40.5958472 126.643508,59.9563389 C128.598735,62.5174945 128.598735,66.070184 126.643508,68.6313396 C111.863396,87.9918313 88.9406729,99.5876785 64.1099282,99.5876785 Z M110.213805,67.5808331 C111.654168,66.0569335 111.654168,63.9430665 110.213805,62.4191669 C99.3257042,50.8995835 82.4391647,44 64.1470385,44 C45.8549124,44 28.9683729,50.8995835 18.0802717,62.4191669 C16.6399094,63.9430665 16.6399094,66.0569335 18.0802717,67.5808331 C28.9683729,79.1004165 45.8549124,86 64.1470385,86 C82.4391647,86 99.3257042,79.1004165 110.213805,67.5808331 Z\"></path>\n <path d=\"M63.5,88 C76.4786916,88 87,77.4786916 87,64.5 C87,51.5213084 76.4786916,41 63.5,41 C50.5213084,41 40,51.5213084 40,64.5 C40,77.4786916 50.5213084,88 63.5,88 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/print-button": {
"title": "$:/core/images/print-button",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-print-button tc-image-button\" viewBox=\"0 0 128 128\" width=\"22pt\" height=\"22pt\">\n <g fill-rule=\"evenodd\">\n <path d=\"M112,71 L112,30.5 L111.96811,30.5 L111.96811,30.5 C111.932942,28.4998414 111.151676,26.510538 109.625176,24.9840387 L86.9982489,2.35711116 C85.3482153,0.707077645 83.1589869,-0.071534047 81,0.0201838424 L81,0 L23.9992458,0 C19.5808867,0 16,3.58213437 16,8.00092105 L16,71 L24,71 L24,8 L81,8 L81,22.4996539 C81,26.9216269 84.5818769,30.5 89.0003461,30.5 L104,30.5 L104,71 L112,71 Z\"></path>\n <rect x=\"32\" y=\"36\" width=\"64\" height=\"8\" rx=\"4\"></rect>\n <rect x=\"32\" y=\"52\" width=\"64\" height=\"8\" rx=\"4\"></rect>\n <rect x=\"32\" y=\"20\" width=\"40\" height=\"8\" rx=\"4\"></rect>\n <path d=\"M0,80.0054195 C0,71.1658704 7.15611005,64 16.0008841,64 L111.999116,64 C120.83616,64 128,71.1553215 128,80.0054195 L128,111.99458 C128,120.83413 120.84389,128 111.999116,128 L16.0008841,128 C7.16383982,128 0,120.844679 0,111.99458 L0,80.0054195 Z M104,96 C108.418278,96 112,92.418278 112,88 C112,83.581722 108.418278,80 104,80 C99.581722,80 96,83.581722 96,88 C96,92.418278 99.581722,96 104,96 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/quote": {
"title": "$:/core/images/quote",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-quote tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M51.2188077,117.712501 L51.2188077,62.1993386 L27.4274524,62.1993386 C27.4274524,53.3075754 29.1096526,45.797753 32.4741035,39.669646 C35.8385544,33.541539 42.0867267,28.9154883 51.2188077,25.7913554 L51.2188077,2 C43.7689521,2.96127169 36.8599155,5.18417913 30.4914905,8.668789 C24.1230656,12.1533989 18.6559149,16.5391352 14.0898743,21.8261295 C9.52383382,27.1131238 5.97919764,33.2411389 3.45585945,40.2103586 C0.932521268,47.1795784 -0.208971741,54.6293222 0.0313461819,62.5598136 L0.0313461819,117.712501 L51.2188077,117.712501 Z M128,117.712501 L128,62.1993386 L104.208645,62.1993386 C104.208645,53.3075754 105.890845,45.797753 109.255296,39.669646 C112.619747,33.541539 118.867919,28.9154883 128,25.7913554 L128,2 C120.550144,2.96127169 113.641108,5.18417913 107.272683,8.668789 C100.904258,12.1533989 95.4371072,16.5391352 90.8710666,21.8261295 C86.3050261,27.1131238 82.7603899,33.2411389 80.2370517,40.2103586 C77.7137136,47.1795784 76.5722206,54.6293222 76.8125385,62.5598136 L76.8125385,117.712501 L128,117.712501 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/refresh-button": {
"title": "$:/core/images/refresh-button",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-refresh-button tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M106.369002,39.4325143 C116.529932,60.3119371 112.939592,86.1974934 95.5979797,103.539105 C73.7286194,125.408466 38.2713806,125.408466 16.4020203,103.539105 C-5.46734008,81.6697449 -5.46734008,46.2125061 16.4020203,24.3431458 C19.5262146,21.2189514 24.5915344,21.2189514 27.7157288,24.3431458 C30.8399231,27.4673401 30.8399231,32.5326599 27.7157288,35.6568542 C12.0947571,51.2778259 12.0947571,76.6044251 27.7157288,92.2253967 C43.3367004,107.846368 68.6632996,107.846368 84.2842712,92.2253967 C97.71993,78.7897379 99.5995262,58.1740623 89.9230597,42.729491 L83.4844861,54.9932839 C81.4307001,58.9052072 76.5945372,60.4115251 72.682614,58.3577391 C68.7706907,56.3039532 67.2643728,51.4677903 69.3181587,47.555867 L84.4354914,18.7613158 C86.4966389,14.8353707 91.3577499,13.3347805 95.273202,15.415792 L124.145886,30.7612457 C128.047354,32.8348248 129.52915,37.6785572 127.455571,41.5800249 C125.381992,45.4814927 120.53826,46.9632892 116.636792,44.8897102 L106.369002,39.4325143 Z M98.1470904,27.0648707 C97.9798954,26.8741582 97.811187,26.6843098 97.6409651,26.4953413 L98.6018187,26.1987327 L98.1470904,27.0648707 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/right-arrow": {
"title": "$:/core/images/right-arrow",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-right-arrow tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <path d=\"M80.3563798,109.353315 C78.9238993,110.786918 76.9450203,111.675144 74.7592239,111.675144 L-4.40893546,111.675144 C-8.77412698,111.675144 -12.3248558,108.130732 -12.3248558,103.758478 C-12.3248558,99.3951199 -8.78077754,95.8418109 -4.40893546,95.8418109 L66.8418109,95.8418109 L66.8418109,24.5910645 C66.8418109,20.225873 70.3862233,16.6751442 74.7584775,16.6751442 C79.1218352,16.6751442 82.6751442,20.2192225 82.6751442,24.5910645 L82.6751442,103.759224 C82.6751442,105.941695 81.7891419,107.920575 80.3566508,109.353886 Z\" transform=\"translate(35.175144, 64.175144) rotate(-45.000000) translate(-35.175144, -64.175144) \"></path>\n</svg>"
},
"$:/core/images/rotate-left": {
"title": "$:/core/images/rotate-left",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-rotate-left tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><rect width=\"32\" height=\"80\" rx=\"8\"/><rect x=\"48\" y=\"96\" width=\"80\" height=\"32\" rx=\"8\"/><path d=\"M61.32 36.65c19.743 2.45 35.023 19.287 35.023 39.693a4 4 0 0 1-8 0c0-15.663-11.254-28.698-26.117-31.46l3.916 3.916a4 4 0 1 1-5.657 5.657L49.172 43.142a4 4 0 0 1 0-5.657l11.313-11.313a4 4 0 1 1 5.657 5.656l-4.821 4.822z\"/></g></svg>"
},
"$:/core/images/save-button": {
"title": "$:/core/images/save-button",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-save-button tc-image-button\" viewBox=\"0 0 128 128\" width=\"22pt\" height=\"22pt\">\n <g fill-rule=\"evenodd\">\n <path d=\"M120.78304,34.329058 C125.424287,43.1924006 128.049406,53.2778608 128.049406,63.9764502 C128.049406,99.3226742 99.3956295,127.97645 64.0494055,127.97645 C28.7031816,127.97645 0.0494055385,99.3226742 0.0494055385,63.9764502 C0.0494055385,28.6302262 28.7031816,-0.0235498012 64.0494055,-0.0235498012 C82.8568763,-0.0235498012 99.769563,8.08898558 111.479045,21.0056358 L114.159581,18.3250998 C117.289194,15.1954866 122.356036,15.1939641 125.480231,18.3181584 C128.598068,21.4359957 128.601317,26.5107804 125.473289,29.6388083 L120.78304,34.329058 Z M108.72451,46.3875877 C110.870571,51.8341374 112.049406,57.767628 112.049406,63.9764502 C112.049406,90.4861182 90.5590735,111.97645 64.0494055,111.97645 C37.5397375,111.97645 16.0494055,90.4861182 16.0494055,63.9764502 C16.0494055,37.4667822 37.5397375,15.9764502 64.0494055,15.9764502 C78.438886,15.9764502 91.3495036,22.308215 100.147097,32.3375836 L58.9411255,73.5435552 L41.975581,56.5780107 C38.8486152,53.4510448 33.7746915,53.4551552 30.6568542,56.5729924 C27.5326599,59.6971868 27.5372202,64.7670668 30.6618725,67.8917192 L53.279253,90.5090997 C54.8435723,92.073419 56.8951519,92.8541315 58.9380216,92.8558261 C60.987971,92.8559239 63.0389578,92.0731398 64.6049211,90.5071765 L108.72451,46.3875877 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/size": {
"title": "$:/core/images/size",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-size tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <path d=\"M92.3431458,26 L83.1715729,35.1715729 C81.6094757,36.73367 81.6094757,39.26633 83.1715729,40.8284271 C84.73367,42.3905243 87.26633,42.3905243 88.8284271,40.8284271 L104.828427,24.8284271 C106.390524,23.26633 106.390524,20.73367 104.828427,19.1715729 L88.8284271,3.17157288 C87.26633,1.60947571 84.73367,1.60947571 83.1715729,3.17157288 C81.6094757,4.73367004 81.6094757,7.26632996 83.1715729,8.82842712 L92.3431457,18 L22,18 C19.790861,18 18,19.790861 18,22 L18,92.3431458 L8.82842712,83.1715729 C7.26632996,81.6094757 4.73367004,81.6094757 3.17157288,83.1715729 C1.60947571,84.73367 1.60947571,87.26633 3.17157288,88.8284271 L19.1715729,104.828427 C20.73367,106.390524 23.26633,106.390524 24.8284271,104.828427 L40.8284271,88.8284271 C42.3905243,87.26633 42.3905243,84.73367 40.8284271,83.1715729 C39.26633,81.6094757 36.73367,81.6094757 35.1715729,83.1715729 L26,92.3431458 L26,22 L22,26 L92.3431458,26 L92.3431458,26 Z M112,52 L112,116 L116,112 L52,112 C49.790861,112 48,113.790861 48,116 C48,118.209139 49.790861,120 52,120 L116,120 C118.209139,120 120,118.209139 120,116 L120,52 C120,49.790861 118.209139,48 116,48 C113.790861,48 112,49.790861 112,52 L112,52 Z\"></path>\n</svg>"
},
"$:/core/images/spiral": {
"title": "$:/core/images/spiral",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-spiral tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"nonzero\">\n <path d=\"M64.534 68.348c3.39 0 6.097-2.62 6.476-5.968l-4.755-.538 4.75.583c.377-3.07-1.194-6.054-3.89-7.78-2.757-1.773-6.34-2.01-9.566-.7-3.46 1.403-6.14 4.392-7.35 8.148l-.01.026c-1.3 4.08-.72 8.64 1.58 12.52 2.5 4.2 6.77 7.2 11.76 8.27 5.37 1.15 11.11-.05 15.83-3.31 5.04-3.51 8.46-9.02 9.45-15.3 1.05-6.7-.72-13.63-4.92-19.19l.02.02c-4.42-5.93-11.2-9.82-18.78-10.78-7.96-1.01-16.13 1.31-22.59 6.43-6.81 5.39-11.18 13.41-12.11 22.26-.98 9.27 1.87 18.65 7.93 26.02 6.32 7.69 15.6 12.56 25.74 13.48 10.54.96 21.15-2.42 29.45-9.4l.01-.01c8.58-7.25 13.94-17.78 14.86-29.21.94-11.84-2.96-23.69-10.86-32.9-8.19-9.5-19.95-15.36-32.69-16.27-13.16-.94-26.24 3.49-36.34 12.34l.01-.01c-10.41 9.08-16.78 22.1-17.68 36.15-.93 14.44 4.03 28.77 13.79 39.78 10.03 11.32 24.28 18.2 39.6 19.09 15.73.92 31.31-4.56 43.24-15.234 12.23-10.954 19.61-26.44 20.5-43.074.14-2.64-1.89-4.89-4.52-5.03-2.64-.14-4.89 1.88-5.03 4.52-.75 14.1-7 27.2-17.33 36.45-10.03 8.98-23.11 13.58-36.3 12.81-12.79-.75-24.67-6.48-33-15.89-8.07-9.11-12.17-20.94-11.41-32.827.74-11.52 5.942-22.15 14.43-29.54l.01-.01c8.18-7.17 18.74-10.75 29.35-9.998 10.21.726 19.6 5.41 26.11 12.96 6.24 7.273 9.32 16.61 8.573 25.894-.718 8.9-4.88 17.064-11.504 22.66l.01-.007c-6.36 5.342-14.44 7.92-22.425 7.19-7.604-.68-14.52-4.314-19.21-10.027-4.44-5.4-6.517-12.23-5.806-18.94.67-6.3 3.76-11.977 8.54-15.766 4.46-3.54 10.05-5.128 15.44-4.44 5.03.63 9.46 3.18 12.32 7.01l.02.024c2.65 3.5 3.75 7.814 3.1 11.92-.59 3.71-2.58 6.925-5.45 8.924-2.56 1.767-5.61 2.403-8.38 1.81-2.42-.516-4.42-1.92-5.53-3.79-.93-1.56-1.15-3.3-.69-4.75l-4.56-1.446L59.325 65c.36-1.12 1.068-1.905 1.84-2.22.25-.103.48-.14.668-.13.06.006.11.015.14.025.01 0 .01 0-.01-.01-.02-.015-.054-.045-.094-.088-.06-.064-.12-.145-.17-.244-.15-.29-.23-.678-.18-1.11l-.005.04c.15-1.332 1.38-2.523 3.035-2.523-2.65 0-4.79 2.144-4.79 4.787s2.14 4.785 4.78 4.785z\"></path>\n </g>\n</svg>"
},
"$:/core/images/stamp": {
"title": "$:/core/images/stamp",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-stamp tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M49.7334301,64 L16.0098166,64 C11.5838751,64 8,67.5829053 8,72.002643 L8,74.4986785 L8,97 L120,97 L120,74.4986785 L120,72.002643 C120,67.5737547 116.413883,64 111.990183,64 L78.2665699,64 C76.502049,60.7519149 75.5,57.0311962 75.5,53.0769231 C75.5,46.6017951 78.1869052,40.7529228 82.5087769,36.5800577 C85.3313113,32.7688808 87,28.0549983 87,22.952183 C87,10.2760423 76.7025492,0 64,0 C51.2974508,0 41,10.2760423 41,22.952183 C41,28.0549983 42.6686887,32.7688808 45.4912231,36.5800577 C49.8130948,40.7529228 52.5,46.6017951 52.5,53.0769231 C52.5,57.0311962 51.497951,60.7519149 49.7334301,64 Z M8,104 L120,104 L120,112 L8,112 L8,104 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/star-filled": {
"title": "$:/core/images/star-filled",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-star-filled tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"nonzero\">\n <path d=\"M61.8361286,96.8228569 L99.1627704,124.110219 C101.883827,126.099427 105.541968,123.420868 104.505636,120.198072 L90.2895569,75.9887263 L89.0292911,79.8977279 L126.314504,52.5528988 C129.032541,50.5595011 127.635256,46.2255025 124.273711,46.2229134 L78.1610486,46.1873965 L81.4604673,48.6032923 L67.1773543,4.41589688 C66.1361365,1.19470104 61.6144265,1.19470104 60.5732087,4.41589688 L46.2900957,48.6032923 L49.5895144,46.1873965 L3.47685231,46.2229134 C0.115307373,46.2255025 -1.28197785,50.5595011 1.43605908,52.5528988 L38.7212719,79.8977279 L37.4610061,75.9887263 L23.2449266,120.198072 C22.2085954,123.420868 25.8667356,126.099427 28.5877926,124.110219 L65.9144344,96.8228569 L61.8361286,96.8228569 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/storyview-classic": {
"title": "$:/core/images/storyview-classic",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-storyview-classic tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M8.00697327,0 C3.58484404,0 0,3.59075293 0,8.00697327 L0,119.993027 C0,124.415156 3.59075293,128 8.00697327,128 L119.993027,128 C124.415156,128 128,124.409247 128,119.993027 L128,8.00697327 C128,3.58484404 124.409247,0 119.993027,0 L8.00697327,0 L8.00697327,0 Z M23.9992458,16 C19.5813843,16 16,19.5776607 16,23.9924054 L16,40.0075946 C16,44.4216782 19.5881049,48 23.9992458,48 L104.000754,48 C108.418616,48 112,44.4223393 112,40.0075946 L112,23.9924054 C112,19.5783218 108.411895,16 104.000754,16 L23.9992458,16 L23.9992458,16 Z M23.9992458,64 C19.5813843,64 16,67.5907123 16,72 C16,76.418278 19.5881049,80 23.9992458,80 L104.000754,80 C108.418616,80 112,76.4092877 112,72 C112,67.581722 108.411895,64 104.000754,64 L23.9992458,64 L23.9992458,64 Z M23.9992458,96 C19.5813843,96 16,99.5907123 16,104 C16,108.418278 19.5881049,112 23.9992458,112 L104.000754,112 C108.418616,112 112,108.409288 112,104 C112,99.581722 108.411895,96 104.000754,96 L23.9992458,96 L23.9992458,96 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/storyview-pop": {
"title": "$:/core/images/storyview-pop",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-storyview-pop tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M8.00697327,0 C3.58484404,0 0,3.59075293 0,8.00697327 L0,119.993027 C0,124.415156 3.59075293,128 8.00697327,128 L119.993027,128 C124.415156,128 128,124.409247 128,119.993027 L128,8.00697327 C128,3.58484404 124.409247,0 119.993027,0 L8.00697327,0 L8.00697327,0 Z M23.9992458,16 C19.5813843,16 16,19.5776607 16,23.9924054 L16,40.0075946 C16,44.4216782 19.5881049,48 23.9992458,48 L104.000754,48 C108.418616,48 112,44.4223393 112,40.0075946 L112,23.9924054 C112,19.5783218 108.411895,16 104.000754,16 L23.9992458,16 L23.9992458,16 Z M16.0098166,56 C11.586117,56 8,59.5776607 8,63.9924054 L8,80.0075946 C8,84.4216782 11.5838751,88 16.0098166,88 L111.990183,88 C116.413883,88 120,84.4223393 120,80.0075946 L120,63.9924054 C120,59.5783218 116.416125,56 111.990183,56 L16.0098166,56 L16.0098166,56 Z M23.9992458,96 C19.5813843,96 16,99.5907123 16,104 C16,108.418278 19.5881049,112 23.9992458,112 L104.000754,112 C108.418616,112 112,108.409288 112,104 C112,99.581722 108.411895,96 104.000754,96 L23.9992458,96 L23.9992458,96 Z M23.9992458,64 C19.5813843,64 16,67.5907123 16,72 C16,76.418278 19.5881049,80 23.9992458,80 L104.000754,80 C108.418616,80 112,76.4092877 112,72 C112,67.581722 108.411895,64 104.000754,64 L23.9992458,64 L23.9992458,64 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/storyview-zoomin": {
"title": "$:/core/images/storyview-zoomin",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-storyview-zoomin tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M8.00697327,0 C3.58484404,0 0,3.59075293 0,8.00697327 L0,119.993027 C0,124.415156 3.59075293,128 8.00697327,128 L119.993027,128 C124.415156,128 128,124.409247 128,119.993027 L128,8.00697327 C128,3.58484404 124.409247,0 119.993027,0 L8.00697327,0 L8.00697327,0 Z M23.9992458,16 C19.5813843,16 16,19.578055 16,24.0085154 L16,71.9914846 C16,76.4144655 19.5881049,80 23.9992458,80 L104.000754,80 C108.418616,80 112,76.421945 112,71.9914846 L112,24.0085154 C112,19.5855345 108.411895,16 104.000754,16 L23.9992458,16 L23.9992458,16 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/strikethrough": {
"title": "$:/core/images/strikethrough",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-strikethrough tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M92.793842,38.7255689 L108.215529,38.7255689 C107.987058,31.985687 106.70193,26.1883331 104.360107,21.3333333 C102.018284,16.4783336 98.8197436,12.4516001 94.7643909,9.25301205 C90.7090382,6.05442399 85.9969032,3.71263572 80.6278447,2.22757697 C75.2587862,0.742518233 69.4328739,0 63.1499331,0 C57.552404,0 52.0977508,0.713959839 46.7858099,2.14190094 C41.473869,3.56984203 36.7331757,5.74027995 32.5635877,8.65327979 C28.3939997,11.5662796 25.0526676,15.2788708 22.5394913,19.7911647 C20.026315,24.3034585 18.7697456,29.6438781 18.7697456,35.8125837 C18.7697456,41.4101128 19.883523,46.0651309 22.1111111,49.7777778 C24.3386992,53.4904246 27.3087722,56.5176144 31.021419,58.8594378 C34.7340659,61.2012612 38.9321497,63.0861151 43.6157965,64.5140562 C48.2994433,65.9419973 53.068695,67.1985666 57.9236948,68.2838019 C62.7786945,69.3690371 67.5479462,70.4256977 72.231593,71.4538153 C76.9152398,72.4819329 81.1133237,73.8241773 84.8259705,75.480589 C88.5386174,77.1370007 91.5086903,79.2788802 93.7362784,81.9062918 C95.9638666,84.5337035 97.0776439,87.9607107 97.0776439,92.1874163 C97.0776439,96.6425926 96.1637753,100.298067 94.3360107,103.153949 C92.5082461,106.009831 90.109341,108.265944 87.1392236,109.922356 C84.1691061,111.578768 80.827774,112.749662 77.1151272,113.435074 C73.4024803,114.120485 69.7184476,114.463186 66.0629183,114.463186 C61.4935068,114.463186 57.0383974,113.892018 52.6974565,112.749665 C48.3565156,111.607312 44.5582492,109.836692 41.3025435,107.437751 C38.0468378,105.03881 35.4194656,101.983062 33.4203481,98.270415 C31.4212305,94.5577681 30.4216867,90.1312171 30.4216867,84.9906292 L15,84.9906292 C15,92.4159229 16.3422445,98.8415614 19.0267738,104.267738 C21.711303,109.693914 25.3667774,114.149023 29.9933066,117.633199 C34.6198357,121.117376 39.9888137,123.71619 46.1004016,125.429719 C52.2119895,127.143248 58.6947448,128 65.5488621,128 C71.1463912,128 76.7723948,127.343157 82.4270415,126.029451 C88.0816882,124.715745 93.1936407,122.602424 97.7630522,119.689424 C102.332464,116.776425 106.073613,113.006717 108.986613,108.380187 C111.899613,103.753658 113.356091,98.1847715 113.356091,91.6733601 C113.356091,85.6188899 112.242314,80.5926126 110.014726,76.5943775 C107.787137,72.5961424 104.817065,69.2833688 101.104418,66.6559572 C97.3917708,64.0285455 93.193687,61.9437828 88.5100402,60.4016064 C83.8263934,58.85943 79.0571416,57.5171855 74.2021419,56.3748327 C69.3471422,55.2324798 64.5778904,54.1758192 59.8942436,53.2048193 C55.2105968,52.2338193 51.012513,51.0058084 47.2998661,49.5207497 C43.5872193,48.0356909 40.6171463,46.1222786 38.3895582,43.7804552 C36.1619701,41.4386318 35.0481928,38.3828836 35.0481928,34.6131191 C35.0481928,30.6148841 35.8192694,27.273552 37.3614458,24.5890228 C38.9036222,21.9044935 40.9598265,19.762614 43.5301205,18.1633199 C46.1004145,16.5640259 49.041929,15.4216902 52.3547523,14.7362784 C55.6675757,14.0508667 59.0374661,13.708166 62.4645248,13.708166 C70.9179361,13.708166 77.8576257,15.6786952 83.2838019,19.6198126 C88.709978,23.56093 91.8799597,29.9294518 92.793842,38.7255689 L92.793842,38.7255689 Z\"></path>\n <rect x=\"5\" y=\"54\" width=\"118\" height=\"16\"></rect>\n </g>\n</svg>"
},
"$:/core/images/subscript": {
"title": "$:/core/images/subscript",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-subscript tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M2.27170276,16 L22.1825093,16 L43.8305003,49.6746527 L66.4138983,16 L85.1220387,16 L53.5854592,61.9685735 L87.3937414,111.411516 L67.0820462,111.411516 L43.295982,74.9306422 L19.1090291,111.411516 L0,111.411516 L33.8082822,61.9685735 L2.27170276,16 Z M127.910914,128.411516 L85.3276227,128.411516 C85.3870139,123.24448 86.6342108,118.730815 89.0692508,114.870386 C91.5042907,111.009956 94.8301491,107.654403 99.0469256,104.803624 C101.066227,103.318844 103.174584,101.878629 105.372059,100.482935 C107.569534,99.0872413 109.588805,97.5876355 111.429933,95.9840726 C113.271061,94.3805097 114.785514,92.6433426 115.973338,90.7725192 C117.161163,88.9016958 117.784761,86.7487964 117.844152,84.3137564 C117.844152,83.1853233 117.710524,81.9826691 117.443264,80.7057579 C117.176003,79.4288467 116.656338,78.2410402 115.884252,77.1423026 C115.112166,76.0435651 114.04314,75.123015 112.677142,74.3806248 C111.311144,73.6382345 109.529434,73.267045 107.331959,73.267045 C105.312658,73.267045 103.634881,73.6679297 102.298579,74.4697112 C100.962276,75.2714926 99.8932503,76.3702137 99.0914688,77.7659073 C98.2896874,79.161601 97.6957841,80.8096826 97.3097412,82.7102016 C96.9236982,84.6107206 96.7009845,86.6596869 96.6415933,88.857162 L86.4857457,88.857162 C86.4857457,85.4124713 86.9460207,82.2202411 87.8665846,79.2803758 C88.7871485,76.3405105 90.1679736,73.801574 92.0091014,71.6634901 C93.8502292,69.5254062 96.092214,67.8476295 98.7351233,66.6301095 C101.378033,65.4125895 104.451482,64.8038386 107.955564,64.8038386 C111.756602,64.8038386 114.933984,65.4274371 117.487807,66.6746527 C120.041629,67.9218683 122.105443,69.4957119 123.67931,71.3962309 C125.253178,73.2967499 126.366746,75.3605638 127.02005,77.5877345 C127.673353,79.8149053 128,81.9381095 128,83.9574109 C128,86.4518421 127.613963,88.7086746 126.841877,90.727976 C126.069791,92.7472774 125.03046,94.6032252 123.723854,96.2958749 C122.417247,97.9885247 120.932489,99.5475208 119.269534,100.97291 C117.60658,102.398299 115.884261,103.734582 114.102524,104.981797 C112.320788,106.229013 110.539078,107.416819 108.757341,108.545253 C106.975605,109.673686 105.327523,110.802102 103.813047,111.930535 C102.298571,113.058968 100.977136,114.231927 99.8487031,115.449447 C98.7202699,116.666967 97.9481956,117.958707 97.5324571,119.324705 L127.910914,119.324705 L127.910914,128.411516 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/superscript": {
"title": "$:/core/images/superscript",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-superscript tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M2.27170276,16 L22.1825093,16 L43.8305003,49.6746527 L66.4138983,16 L85.1220387,16 L53.5854592,61.9685735 L87.3937414,111.411516 L67.0820462,111.411516 L43.295982,74.9306422 L19.1090291,111.411516 L0,111.411516 L33.8082822,61.9685735 L2.27170276,16 Z M127.910914,63.4115159 L85.3276227,63.4115159 C85.3870139,58.2444799 86.6342108,53.7308149 89.0692508,49.8703857 C91.5042907,46.0099565 94.8301491,42.654403 99.0469256,39.8036245 C101.066227,38.318844 103.174584,36.8786285 105.372059,35.4829349 C107.569534,34.0872413 109.588805,32.5876355 111.429933,30.9840726 C113.271061,29.3805097 114.785514,27.6433426 115.973338,25.7725192 C117.161163,23.9016958 117.784761,21.7487964 117.844152,19.3137564 C117.844152,18.1853233 117.710524,16.9826691 117.443264,15.7057579 C117.176003,14.4288467 116.656338,13.2410402 115.884252,12.1423026 C115.112166,11.0435651 114.04314,10.123015 112.677142,9.38062477 C111.311144,8.63823453 109.529434,8.26704499 107.331959,8.26704499 C105.312658,8.26704499 103.634881,8.6679297 102.298579,9.46971115 C100.962276,10.2714926 99.8932503,11.3702137 99.0914688,12.7659073 C98.2896874,14.161601 97.6957841,15.8096826 97.3097412,17.7102016 C96.9236982,19.6107206 96.7009845,21.6596869 96.6415933,23.857162 L86.4857457,23.857162 C86.4857457,20.4124713 86.9460207,17.2202411 87.8665846,14.2803758 C88.7871485,11.3405105 90.1679736,8.80157397 92.0091014,6.6634901 C93.8502292,4.52540622 96.092214,2.84762946 98.7351233,1.63010947 C101.378033,0.412589489 104.451482,-0.196161372 107.955564,-0.196161372 C111.756602,-0.196161372 114.933984,0.427437071 117.487807,1.67465266 C120.041629,2.92186826 122.105443,4.49571195 123.67931,6.39623095 C125.253178,8.29674995 126.366746,10.3605638 127.02005,12.5877345 C127.673353,14.8149053 128,16.9381095 128,18.9574109 C128,21.4518421 127.613963,23.7086746 126.841877,25.727976 C126.069791,27.7472774 125.03046,29.6032252 123.723854,31.2958749 C122.417247,32.9885247 120.932489,34.5475208 119.269534,35.97291 C117.60658,37.3982993 115.884261,38.7345816 114.102524,39.9817972 C112.320788,41.2290128 110.539078,42.4168194 108.757341,43.5452525 C106.975605,44.6736857 105.327523,45.8021019 103.813047,46.9305351 C102.298571,48.0589682 100.977136,49.2319272 99.8487031,50.4494472 C98.7202699,51.6669672 97.9481956,52.9587068 97.5324571,54.3247048 L127.910914,54.3247048 L127.910914,63.4115159 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/tag-button": {
"title": "$:/core/images/tag-button",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-tag-button tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M18.1643182,47.6600756 L18.1677196,51.7651887 C18.1708869,55.5878829 20.3581578,60.8623899 23.0531352,63.5573673 L84.9021823,125.406414 C87.5996731,128.103905 91.971139,128.096834 94.6717387,125.396234 L125.766905,94.3010679 C128.473612,91.5943612 128.472063,87.2264889 125.777085,84.5315115 L63.9280381,22.6824644 C61.2305472,19.9849735 55.9517395,17.801995 52.1318769,17.8010313 L25.0560441,17.7942007 C21.2311475,17.7932358 18.1421354,20.8872832 18.1452985,24.7049463 L18.1535504,34.6641936 C18.2481119,34.6754562 18.3439134,34.6864294 18.4409623,34.6971263 C22.1702157,35.1081705 26.9295004,34.6530132 31.806204,33.5444844 C32.1342781,33.0700515 32.5094815,32.6184036 32.9318197,32.1960654 C35.6385117,29.4893734 39.5490441,28.718649 42.94592,29.8824694 C43.0432142,29.8394357 43.1402334,29.7961748 43.2369683,29.7526887 L43.3646982,30.0368244 C44.566601,30.5115916 45.6933052,31.2351533 46.6655958,32.2074439 C50.4612154,36.0030635 50.4663097,42.1518845 46.6769742,45.94122 C43.0594074,49.5587868 37.2914155,49.7181264 33.4734256,46.422636 C28.1082519,47.5454734 22.7987486,48.0186448 18.1643182,47.6600756 Z\"></path>\n <path d=\"M47.6333528,39.5324628 L47.6562932,39.5834939 C37.9670934,43.9391617 26.0718874,46.3819521 17.260095,45.4107025 C5.27267473,44.0894301 -1.02778744,36.4307276 2.44271359,24.0779512 C5.56175386,12.9761516 14.3014034,4.36129832 24.0466405,1.54817001 C34.7269254,-1.53487574 43.7955833,3.51606438 43.7955834,14.7730751 L35.1728168,14.7730752 C35.1728167,9.91428944 32.0946059,8.19982862 26.4381034,9.83267419 C19.5270911,11.8276553 13.046247,18.2159574 10.7440788,26.4102121 C8.82861123,33.2280582 11.161186,36.0634845 18.2047888,36.8398415 C25.3302805,37.6252244 35.7353482,35.4884477 44.1208333,31.7188498 L44.1475077,31.7781871 C44.159701,31.7725635 44.1718402,31.7671479 44.1839238,31.7619434 C45.9448098,31.0035157 50.4503245,38.3109156 47.7081571,39.5012767 C47.6834429,39.512005 47.6585061,39.5223987 47.6333528,39.5324628 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/theme-button": {
"title": "$:/core/images/theme-button",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-theme-button tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M55.854113,66.9453198 C54.3299482,65.1432292 53.0133883,63.518995 51.9542746,62.1263761 C40.8899947,47.578055 35.3091807,55.2383404 28.9941893,62.1263758 C22.6791979,69.0144112 30.6577916,74.5954741 24.6646171,79.4611023 C18.6714426,84.3267304 19.0414417,86.0133155 8.92654943,77.1119468 C-1.18834284,68.2105781 -1.88793412,65.7597832 2.7553553,60.6807286 C7.39864472,55.601674 11.2794845,63.5989423 20.7646627,54.5728325 C30.2498409,45.5467226 22.2819131,37.5470737 22.2819131,37.5470737 C22.2819131,37.5470737 42.0310399,-2.82433362 68.4206088,0.157393922 C94.8101776,3.13912147 58.4373806,-3.70356506 49.3898693,27.958066 C45.5161782,41.5139906 50.1107906,38.3197672 57.4560458,44.0453955 C59.1625767,45.3756367 63.8839488,48.777453 70.127165,53.3625321 C63.9980513,59.2416709 58.9704753,64.0315459 55.854113,66.9453198 Z M67.4952439,79.8919946 C83.5082212,96.9282402 105.237121,117.617674 112.611591,120.312493 C123.044132,124.12481 128.000001,117.170903 128,105.522947 C127.999999,98.3705516 104.170675,78.980486 84.0760493,63.7529565 C76.6683337,70.9090328 70.7000957,76.7055226 67.4952439,79.8919946 Z\"></path>\n <path d=\"M58.2852966,138.232794 L58.2852966,88.3943645 C56.318874,88.3923153 54.7254089,86.7952906 54.7254089,84.8344788 C54.7254089,82.8684071 56.3175932,81.2745911 58.2890859,81.2745911 L79.6408336,81.2745911 C81.608998,81.2745911 83.2045105,82.8724076 83.2045105,84.8344788 C83.2045105,86.7992907 81.614366,88.3923238 79.6446228,88.3943645 L79.6446228,88.3943646 L79.6446228,138.232794 C79.6446228,144.131009 74.8631748,148.912457 68.9649597,148.912457 C63.0667446,148.912457 58.2852966,144.131009 58.2852966,138.232794 Z M65.405072,-14.8423767 L72.5248474,-14.8423767 L76.0847351,-0.690681892 L72.5248474,6.51694947 L72.5248474,81.2745911 L65.405072,81.2745911 L65.405072,6.51694947 L61.8451843,-0.690681892 L65.405072,-14.8423767 Z\" transform=\"translate(68.964960, 67.035040) rotate(45.000000) translate(-68.964960, -67.035040) \"></path>\n </g>\n</svg>"
},
"$:/core/images/timestamp-off": {
"title": "$:/core/images/timestamp-off",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-timestamp-off tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M58.25 11C26.08 11 0 37.082 0 69.25s26.08 58.25 58.25 58.25c32.175 0 58.25-26.082 58.25-58.25S90.425 11 58.25 11zm0 100.5C34.914 111.5 16 92.586 16 69.25 16 45.92 34.914 27 58.25 27s42.25 18.92 42.25 42.25c0 23.336-18.914 42.25-42.25 42.25zM49.704 10c-2.762 0-5-2.24-5-5-.004-2.756 2.238-5 5-5H66.69c2.762 0 5.002 2.24 5 5 .006 2.757-2.238 5-5 5H49.705z\"/><path d=\"M58.25 35.88c-18.777 0-33.998 15.224-33.998 33.998 0 18.773 15.22 34.002 33.998 34.002 18.784 0 34.002-15.23 34.002-34.002 0-18.774-15.218-33.998-34.002-33.998zm-3.03 50.123H44.196v-34H55.22v34zm16.976 0H61.17v-34h11.025v34z\"/>\n </g>\n</svg>\n"
},
"$:/core/images/timestamp-on": {
"title": "$:/core/images/timestamp-on",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-timestamp-on tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M58.25 11C26.08 11 0 37.082 0 69.25s26.08 58.25 58.25 58.25c32.175 0 58.25-26.082 58.25-58.25S90.425 11 58.25 11zm0 100.5C34.914 111.5 16 92.586 16 69.25 16 45.92 34.914 27 58.25 27s42.25 18.92 42.25 42.25c0 23.336-18.914 42.25-42.25 42.25zM49.704 10c-2.762 0-5-2.24-5-5-.004-2.756 2.238-5 5-5H66.69c2.762 0 5.002 2.24 5 5 .006 2.757-2.238 5-5 5H49.705z\"/><path d=\"M13.41 27.178c-2.116 1.775-5.27 1.498-7.045-.613-1.772-2.11-1.498-5.27.616-7.047l9.95-8.348c2.115-1.774 5.27-1.5 7.045.618 1.775 2.108 1.498 5.27-.616 7.043l-9.95 8.348zM102.983 27.178c2.116 1.775 5.27 1.498 7.045-.613 1.772-2.11 1.498-5.27-.616-7.047l-9.95-8.348c-2.114-1.774-5.27-1.5-7.044.618-1.775 2.108-1.498 5.27.616 7.043l9.95 8.348zM65.097 71.072c0 3.826-3.09 6.928-6.897 6.928-3.804.006-6.9-3.102-6.903-6.928 0 0 4.76-39.072 6.903-39.072s6.897 39.072 6.897 39.072z\"/>\n </g>\n</svg>\n"
},
"$:/core/images/tip": {
"title": "$:/core/images/tip",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-tip tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M64,128.241818 C99.346224,128.241818 128,99.5880417 128,64.2418177 C128,28.8955937 99.346224,0.241817675 64,0.241817675 C28.653776,0.241817675 0,28.8955937 0,64.2418177 C0,99.5880417 28.653776,128.241818 64,128.241818 Z M75.9358659,91.4531941 C75.3115438,95.581915 70.2059206,98.8016748 64,98.8016748 C57.7940794,98.8016748 52.6884562,95.581915 52.0641341,91.4531941 C54.3299053,94.0502127 58.8248941,95.8192805 64,95.8192805 C69.1751059,95.8192805 73.6700947,94.0502127 75.9358659,91.4531941 L75.9358659,91.4531941 Z M75.9358659,95.9453413 C75.3115438,100.074062 70.2059206,103.293822 64,103.293822 C57.7940794,103.293822 52.6884562,100.074062 52.0641341,95.9453413 C54.3299053,98.5423599 58.8248941,100.311428 64,100.311428 C69.1751059,100.311428 73.6700947,98.5423599 75.9358659,95.9453413 L75.9358659,95.9453413 Z M75.9358659,100.40119 C75.3115438,104.529911 70.2059206,107.74967 64,107.74967 C57.7940794,107.74967 52.6884562,104.529911 52.0641341,100.40119 C54.3299053,102.998208 58.8248941,104.767276 64,104.767276 C69.1751059,104.767276 73.6700947,102.998208 75.9358659,100.40119 L75.9358659,100.40119 Z M75.9358659,104.893337 C75.3115438,109.022058 70.2059206,112.241818 64,112.241818 C57.7940794,112.241818 52.6884562,109.022058 52.0641341,104.893337 C54.3299053,107.490356 58.8248941,109.259423 64,109.259423 C69.1751059,109.259423 73.6700947,107.490356 75.9358659,104.893337 L75.9358659,104.893337 Z M64.3010456,24.2418177 C75.9193117,24.2418188 88.0000013,32.0619847 88,48.4419659 C87.9999987,64.8219472 75.9193018,71.7540963 75.9193021,83.5755932 C75.9193022,89.4486648 70.0521957,92.8368862 63.9999994,92.8368862 C57.947803,92.8368862 51.9731007,89.8295115 51.9731007,83.5755932 C51.9731007,71.1469799 39.9999998,65.4700602 40,48.4419647 C40.0000002,31.4138691 52.6827796,24.2418166 64.3010456,24.2418177 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/transcludify": {
"title": "$:/core/images/transcludify",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-transcludify-button tc-image-button\" viewBox=\"0 0 128 128\" width=\"22pt\" height=\"22pt\"><path d=\"M0 59.482c.591 0 1.36-.089 2.306-.266a10.417 10.417 0 0 0 2.75-.932 6.762 6.762 0 0 0 2.306-1.907c.651-.828.976-1.863.976-3.104V35.709c0-2.01.414-3.74 1.242-5.19.828-1.448 1.833-2.66 3.016-3.636s2.425-1.7 3.726-2.173c1.3-.473 2.424-.71 3.37-.71h8.073v7.451h-4.88c-1.241 0-2.232.207-2.97.621-.74.414-1.302.932-1.686 1.552a4.909 4.909 0 0 0-.71 1.996c-.089.71-.133 1.39-.133 2.04v16.677c0 1.715-.325 3.134-.976 4.258-.65 1.123-1.434 2.025-2.35 2.705-.917.68-1.863 1.168-2.839 1.464-.976.296-1.818.473-2.528.532v.178c.71.059 1.552.207 2.528.443.976.237 1.922.68 2.839 1.33.916.651 1.7 1.583 2.35 2.795.65 1.212.976 2.853.976 4.923v16.144c0 .65.044 1.33.133 2.04.089.71.325 1.375.71 1.996.384.621.946 1.139 1.685 1.553.74.414 1.73.62 2.972.62h4.879v7.452h-8.073c-.946 0-2.07-.237-3.37-.71-1.301-.473-2.543-1.197-3.726-2.173-1.183-.976-2.188-2.188-3.016-3.637-.828-1.449-1.242-3.179-1.242-5.19V74.119c0-1.42-.325-2.572-.976-3.46-.65-.886-1.419-1.581-2.306-2.084a8.868 8.868 0 0 0-2.75-1.02C1.36 67.377.591 67.288 0 67.288v-7.806zm24.66 0c.591 0 1.36-.089 2.306-.266a10.417 10.417 0 0 0 2.75-.932 6.762 6.762 0 0 0 2.306-1.907c.65-.828.976-1.863.976-3.104V35.709c0-2.01.414-3.74 1.242-5.19.828-1.448 1.833-2.66 3.016-3.636s2.425-1.7 3.726-2.173c1.3-.473 2.424-.71 3.37-.71h8.073v7.451h-4.88c-1.241 0-2.232.207-2.97.621-.74.414-1.302.932-1.686 1.552a4.909 4.909 0 0 0-.71 1.996c-.089.71-.133 1.39-.133 2.04v16.677c0 1.715-.325 3.134-.976 4.258-.65 1.123-1.434 2.025-2.35 2.705-.917.68-1.863 1.168-2.839 1.464-.976.296-1.818.473-2.528.532v.178c.71.059 1.552.207 2.528.443.976.237 1.922.68 2.839 1.33.916.651 1.7 1.583 2.35 2.795.65 1.212.976 2.853.976 4.923v16.144c0 .65.044 1.33.133 2.04.089.71.325 1.375.71 1.996.384.621.946 1.139 1.685 1.553.74.414 1.73.62 2.972.62h4.879v7.452h-8.073c-.946 0-2.07-.237-3.37-.71-1.301-.473-2.543-1.197-3.726-2.173-1.183-.976-2.188-2.188-3.016-3.637-.828-1.449-1.242-3.179-1.242-5.19V74.119c0-1.42-.325-2.572-.976-3.46-.65-.886-1.419-1.581-2.306-2.084a8.868 8.868 0 0 0-2.75-1.02c-.946-.177-1.715-.266-2.306-.266v-7.806zm43.965-3.538L80.6 52.041l2.306 7.097-12.063 3.903 7.628 10.378-6.12 4.435-7.63-10.467-7.45 10.201-5.943-4.524 7.628-10.023-12.152-4.17 2.306-7.096 12.064 4.17V43.347h7.451v12.596zm34.425 11.344c-.65 0-1.449.089-2.395.266-.946.177-1.863.488-2.75.931a6.356 6.356 0 0 0-2.262 1.908c-.62.828-.931 1.862-.931 3.104v17.564c0 2.01-.414 3.74-1.242 5.189-.828 1.449-1.833 2.661-3.016 3.637s-2.425 1.7-3.726 2.173c-1.3.473-2.424.71-3.37.71h-8.073v-7.451h4.88c1.241 0 2.232-.207 2.97-.621.74-.414 1.302-.932 1.686-1.553a4.9 4.9 0 0 0 .71-1.995c.089-.71.133-1.39.133-2.04V72.432c0-1.715.325-3.134.976-4.258.65-1.124 1.434-2.01 2.35-2.661.917-.65 1.863-1.124 2.839-1.42.976-.295 1.818-.502 2.528-.62v-.178c-.71-.059-1.552-.207-2.528-.443-.976-.237-1.922-.68-2.839-1.33-.916-.651-1.7-1.583-2.35-2.795-.65-1.212-.976-2.853-.976-4.923V37.66c0-.651-.044-1.331-.133-2.04a4.909 4.909 0 0 0-.71-1.997c-.384-.62-.946-1.138-1.685-1.552-.74-.414-1.73-.62-2.972-.62h-4.879V24h8.073c.946 0 2.07.237 3.37.71 1.301.473 2.543 1.197 3.726 2.173 1.183.976 2.188 2.188 3.016 3.637.828 1.449 1.242 3.178 1.242 5.189v16.943c0 1.419.31 2.572.931 3.46a6.897 6.897 0 0 0 2.262 2.084 8.868 8.868 0 0 0 2.75 1.02c.946.177 1.745.266 2.395.266v7.806zm24.66 0c-.65 0-1.449.089-2.395.266-.946.177-1.863.488-2.75.931a6.356 6.356 0 0 0-2.262 1.908c-.62.828-.931 1.862-.931 3.104v17.564c0 2.01-.414 3.74-1.242 5.189-.828 1.449-1.833 2.661-3.016 3.637s-2.425 1.7-3.726 2.173c-1.3.473-2.424.71-3.37.71h-8.073v-7.451h4.88c1.241 0 2.232-.207 2.97-.621.74-.414 1.302-.932 1.686-1.553a4.9 4.9 0 0 0 .71-1.995c.089-.71.133-1.39.133-2.04V72.432c0-1.715.325-3.134.976-4.258.65-1.124 1.434-2.01 2.35-2.661.917-.65 1.863-1.124 2.839-1.42.976-.295 1.818-.502 2.528-.62v-.178c-.71-.059-1.552-.207-2.528-.443-.976-.237-1.922-.68-2.839-1.33-.916-.651-1.7-1.583-2.35-2.795-.65-1.212-.976-2.853-.976-4.923V37.66c0-.651-.044-1.331-.133-2.04a4.909 4.909 0 0 0-.71-1.997c-.384-.62-.946-1.138-1.685-1.552-.74-.414-1.73-.62-2.972-.62h-4.879V24h8.073c.946 0 2.07.237 3.37.71 1.301.473 2.543 1.197 3.726 2.173 1.183.976 2.188 2.188 3.016 3.637.828 1.449 1.242 3.178 1.242 5.189v16.943c0 1.419.31 2.572.931 3.46a6.897 6.897 0 0 0 2.262 2.084 8.868 8.868 0 0 0 2.75 1.02c.946.177 1.745.266 2.395.266v7.806z\" fill-rule=\"evenodd\"/></svg>\n"
},
"$:/core/images/twitter": {
"title": "$:/core/images/twitter",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-twitter tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M41.6263422,115.803477 C27.0279663,115.803477 13.4398394,111.540813 1.99987456,104.234833 C4.02221627,104.472643 6.08004574,104.594302 8.16644978,104.594302 C20.277456,104.594302 31.4238403,100.47763 40.270894,93.5715185 C28.9590538,93.3635501 19.4123842,85.9189246 16.1230832,75.6885328 C17.7011365,75.9892376 19.320669,76.1503787 20.9862896,76.1503787 C23.344152,76.1503787 25.6278127,75.8359011 27.7971751,75.247346 C15.9709927,72.8821073 7.06079851,62.4745062 7.06079851,49.9982394 C7.06079851,49.8898938 7.06079851,49.7820074 7.06264203,49.67458 C10.5482779,51.6032228 14.5339687,52.7615103 18.7717609,52.8951059 C11.8355159,48.277565 7.2714207,40.3958845 7.2714207,31.4624258 C7.2714207,26.7434257 8.54621495,22.3200804 10.7713439,18.5169676 C23.5211299,34.0957738 42.568842,44.3472839 64.0532269,45.4210985 C63.6126256,43.5365285 63.3835682,41.5711584 63.3835682,39.5529928 C63.3835682,25.3326379 74.95811,13.8034766 89.2347917,13.8034766 C96.6697089,13.8034766 103.387958,16.930807 108.103682,21.9353619 C113.991886,20.780288 119.52429,18.6372496 124.518847,15.6866694 C122.588682,21.6993889 118.490075,26.7457211 113.152623,29.9327334 C118.381769,29.3102055 123.363882,27.926045 127.999875,25.8780385 C124.534056,31.0418981 120.151087,35.5772616 115.100763,39.2077561 C115.150538,40.3118708 115.175426,41.4224128 115.175426,42.538923 C115.175426,76.5663154 89.1744164,115.803477 41.6263422,115.803477\"></path>\n </g>\n</svg>\n"
},
"$:/core/images/underline": {
"title": "$:/core/images/underline",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-underline tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M7,117.421488 L121.247934,117.421488 L121.247934,128 L7,128 L7,117.421488 Z M104.871212,98.8958333 L104.871212,0 L88.6117424,0 L88.6117424,55.8560606 C88.6117424,60.3194668 88.0060035,64.432115 86.7945076,68.1941288 C85.5830116,71.9561425 83.7657949,75.239885 81.342803,78.0454545 C78.9198111,80.8510241 75.8911167,83.0189317 72.2566288,84.5492424 C68.6221409,86.0795531 64.3182067,86.844697 59.344697,86.844697 C53.0959284,86.844697 48.1862552,85.0593613 44.6155303,81.4886364 C41.0448054,77.9179114 39.2594697,73.0720003 39.2594697,66.9507576 L39.2594697,0 L23,0 L23,65.0378788 C23,70.3939662 23.5419769,75.2717583 24.625947,79.6714015 C25.709917,84.0710447 27.5908957,87.864883 30.2689394,91.0530303 C32.9469831,94.2411776 36.4538925,96.6960141 40.7897727,98.4176136 C45.125653,100.139213 50.545422,101 57.0492424,101 C64.3182182,101 70.630655,99.5653553 75.9867424,96.6960227 C81.3428298,93.8266902 85.742407,89.33147 89.1856061,83.2102273 L89.5681818,83.2102273 L89.5681818,98.8958333 L104.871212,98.8958333 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/unfold-all-button": {
"title": "$:/core/images/unfold-all-button",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-unfold-all tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <rect x=\"0\" y=\"0\" width=\"128\" height=\"16\" rx=\"8\"></rect>\n <rect x=\"0\" y=\"64\" width=\"128\" height=\"16\" rx=\"8\"></rect>\n <path d=\"M85.598226,8.34884273 C84.1490432,6.89863875 82.1463102,6 79.9340286,6 L47.9482224,6 C43.5292967,6 39.9411255,9.581722 39.9411255,14 C39.9411255,18.4092877 43.5260249,22 47.9482224,22 L71.9411255,22 L71.9411255,45.9929031 C71.9411255,50.4118288 75.5228475,54 79.9411255,54 C84.3504132,54 87.9411255,50.4151006 87.9411255,45.9929031 L87.9411255,14.0070969 C87.9411255,11.7964515 87.0447363,9.79371715 85.5956548,8.34412458 Z\" transform=\"translate(63.941125, 30.000000) scale(1, -1) rotate(-45.000000) translate(-63.941125, -30.000000) \"></path>\n <path d=\"M85.6571005,72.2899682 C84.2079177,70.8397642 82.2051847,69.9411255 79.9929031,69.9411255 L48.0070969,69.9411255 C43.5881712,69.9411255 40,73.5228475 40,77.9411255 C40,82.3504132 43.5848994,85.9411255 48.0070969,85.9411255 L72,85.9411255 L72,109.934029 C72,114.352954 75.581722,117.941125 80,117.941125 C84.4092877,117.941125 88,114.356226 88,109.934029 L88,77.9482224 C88,75.737577 87.1036108,73.7348426 85.6545293,72.2852501 Z\" transform=\"translate(64.000000, 93.941125) scale(1, -1) rotate(-45.000000) translate(-64.000000, -93.941125) \"></path>\n </g>\n</svg>"
},
"$:/core/images/unfold-button": {
"title": "$:/core/images/unfold-button",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-unfold tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <rect x=\"0\" y=\"0\" width=\"128\" height=\"16\" rx=\"8\"></rect>\n <path d=\"M85.598226,11.3488427 C84.1490432,9.89863875 82.1463102,9 79.9340286,9 L47.9482224,9 C43.5292967,9 39.9411255,12.581722 39.9411255,17 C39.9411255,21.4092877 43.5260249,25 47.9482224,25 L71.9411255,25 L71.9411255,48.9929031 C71.9411255,53.4118288 75.5228475,57 79.9411255,57 C84.3504132,57 87.9411255,53.4151006 87.9411255,48.9929031 L87.9411255,17.0070969 C87.9411255,14.7964515 87.0447363,12.7937171 85.5956548,11.3441246 Z\" transform=\"translate(63.941125, 33.000000) scale(1, -1) rotate(-45.000000) translate(-63.941125, -33.000000) \"></path>\n <path d=\"M85.6571005,53.4077172 C84.2079177,51.9575133 82.2051847,51.0588745 79.9929031,51.0588745 L48.0070969,51.0588745 C43.5881712,51.0588745 40,54.6405965 40,59.0588745 C40,63.4681622 43.5848994,67.0588745 48.0070969,67.0588745 L72,67.0588745 L72,91.0517776 C72,95.4707033 75.581722,99.0588745 80,99.0588745 C84.4092877,99.0588745 88,95.4739751 88,91.0517776 L88,59.0659714 C88,56.855326 87.1036108,54.8525917 85.6545293,53.4029991 Z\" transform=\"translate(64.000000, 75.058875) scale(1, -1) rotate(-45.000000) translate(-64.000000, -75.058875) \"></path>\n </g>\n</svg>"
},
"$:/core/images/unlocked-padlock": {
"title": "$:/core/images/unlocked-padlock",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-unlocked-padlock tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M48.6266053,64 L105,64 L105,96.0097716 C105,113.673909 90.6736461,128 73.001193,128 L55.998807,128 C38.3179793,128 24,113.677487 24,96.0097716 L24,64 L30.136303,64 C19.6806213,51.3490406 2.77158986,28.2115132 25.8366966,8.85759246 C50.4723026,-11.8141335 71.6711028,13.2108337 81.613302,25.0594855 C91.5555012,36.9081373 78.9368488,47.4964439 69.1559674,34.9513593 C59.375086,22.4062748 47.9893192,10.8049522 35.9485154,20.9083862 C23.9077117,31.0118202 34.192312,43.2685325 44.7624679,55.8655518 C47.229397,58.805523 48.403443,61.5979188 48.6266053,64 Z M67.7315279,92.3641717 C70.8232551,91.0923621 73,88.0503841 73,84.5 C73,79.8055796 69.1944204,76 64.5,76 C59.8055796,76 56,79.8055796 56,84.5 C56,87.947435 58.0523387,90.9155206 61.0018621,92.2491029 L55.9067479,115.020857 L72.8008958,115.020857 L67.7315279,92.3641717 L67.7315279,92.3641717 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/up-arrow": {
"title": "$:/core/images/up-arrow",
"created": "20150316000544368",
"modified": "20150316000831867",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-up-arrow tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n<path transform=\"rotate(-135, 63.8945, 64.1752)\" d=\"m109.07576,109.35336c-1.43248,1.43361 -3.41136,2.32182 -5.59717,2.32182l-79.16816,0c-4.36519,0 -7.91592,-3.5444 -7.91592,-7.91666c0,-4.36337 3.54408,-7.91667 7.91592,-7.91667l71.25075,0l0,-71.25074c0,-4.3652 3.54442,-7.91592 7.91667,-7.91592c4.36336,0 7.91667,3.54408 7.91667,7.91592l0,79.16815c0,2.1825 -0.88602,4.16136 -2.3185,5.59467l-0.00027,-0.00056l0.00001,-0.00001z\" />\n</svg>\n \n"
},
"$:/core/images/video": {
"title": "$:/core/images/video",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-video tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M64,12 C29.0909091,12 8.72727273,14.9166667 5.81818182,17.8333333 C2.90909091,20.75 1.93784382e-15,41.1666667 0,64.5 C1.93784382e-15,87.8333333 2.90909091,108.25 5.81818182,111.166667 C8.72727273,114.083333 29.0909091,117 64,117 C98.9090909,117 119.272727,114.083333 122.181818,111.166667 C125.090909,108.25 128,87.8333333 128,64.5 C128,41.1666667 125.090909,20.75 122.181818,17.8333333 C119.272727,14.9166667 98.9090909,12 64,12 Z M54.9161194,44.6182253 C51.102648,42.0759111 48.0112186,43.7391738 48.0112186,48.3159447 L48.0112186,79.6840553 C48.0112186,84.2685636 51.109784,85.9193316 54.9161194,83.3817747 L77.0838806,68.6032672 C80.897352,66.0609529 80.890216,61.9342897 77.0838806,59.3967328 L54.9161194,44.6182253 Z\"></path>\n </g>\n</svg>"
},
"$:/core/images/warning": {
"title": "$:/core/images/warning",
"tags": "$:/tags/Image",
"text": "<svg class=\"tc-image-warning tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n <g fill-rule=\"evenodd\">\n <path d=\"M57.0717968,11 C60.1509982,5.66666667 67.8490018,5.66666667 70.9282032,11 L126.353829,107 C129.433031,112.333333 125.584029,119 119.425626,119 L8.57437416,119 C2.41597129,119 -1.43303051,112.333333 1.64617093,107 L57.0717968,11 Z M64,37 C59.581722,37 56,40.5820489 56,44.9935776 L56,73.0064224 C56,77.4211534 59.5907123,81 64,81 C68.418278,81 72,77.4179511 72,73.0064224 L72,44.9935776 C72,40.5788466 68.4092877,37 64,37 Z M64,104 C68.418278,104 72,100.418278 72,96 C72,91.581722 68.418278,88 64,88 C59.581722,88 56,91.581722 56,96 C56,100.418278 59.581722,104 64,104 Z\"></path>\n </g>\n</svg>"
},
"$:/language/Buttons/AdvancedSearch/Caption": {
"title": "$:/language/Buttons/AdvancedSearch/Caption",
"text": "advanced search"
},
"$:/language/Buttons/AdvancedSearch/Hint": {
"title": "$:/language/Buttons/AdvancedSearch/Hint",
"text": "Advanced search"
},
"$:/language/Buttons/Cancel/Caption": {
"title": "$:/language/Buttons/Cancel/Caption",
"text": "cancel"
},
"$:/language/Buttons/Cancel/Hint": {
"title": "$:/language/Buttons/Cancel/Hint",
"text": "Discard changes to this tiddler"
},
"$:/language/Buttons/Clone/Caption": {
"title": "$:/language/Buttons/Clone/Caption",
"text": "clone"
},
"$:/language/Buttons/Clone/Hint": {
"title": "$:/language/Buttons/Clone/Hint",
"text": "Clone this tiddler"
},
"$:/language/Buttons/Close/Caption": {
"title": "$:/language/Buttons/Close/Caption",
"text": "close"
},
"$:/language/Buttons/Close/Hint": {
"title": "$:/language/Buttons/Close/Hint",
"text": "Close this tiddler"
},
"$:/language/Buttons/CloseAll/Caption": {
"title": "$:/language/Buttons/CloseAll/Caption",
"text": "close all"
},
"$:/language/Buttons/CloseAll/Hint": {
"title": "$:/language/Buttons/CloseAll/Hint",
"text": "Close all tiddlers"
},
"$:/language/Buttons/CloseOthers/Caption": {
"title": "$:/language/Buttons/CloseOthers/Caption",
"text": "close others"
},
"$:/language/Buttons/CloseOthers/Hint": {
"title": "$:/language/Buttons/CloseOthers/Hint",
"text": "Close other tiddlers"
},
"$:/language/Buttons/ControlPanel/Caption": {
"title": "$:/language/Buttons/ControlPanel/Caption",
"text": "control panel"
},
"$:/language/Buttons/ControlPanel/Hint": {
"title": "$:/language/Buttons/ControlPanel/Hint",
"text": "Open control panel"
},
"$:/language/Buttons/CopyToClipboard/Caption": {
"title": "$:/language/Buttons/CopyToClipboard/Caption",
"text": "copy to clipboard"
},
"$:/language/Buttons/CopyToClipboard/Hint": {
"title": "$:/language/Buttons/CopyToClipboard/Hint",
"text": "Copy this text to the clipboard"
},
"$:/language/Buttons/Delete/Caption": {
"title": "$:/language/Buttons/Delete/Caption",
"text": "delete"
},
"$:/language/Buttons/Delete/Hint": {
"title": "$:/language/Buttons/Delete/Hint",
"text": "Delete this tiddler"
},
"$:/language/Buttons/Edit/Caption": {
"title": "$:/language/Buttons/Edit/Caption",
"text": "edit"
},
"$:/language/Buttons/Edit/Hint": {
"title": "$:/language/Buttons/Edit/Hint",
"text": "Edit this tiddler"
},
"$:/language/Buttons/Encryption/Caption": {
"title": "$:/language/Buttons/Encryption/Caption",
"text": "encryption"
},
"$:/language/Buttons/Encryption/Hint": {
"title": "$:/language/Buttons/Encryption/Hint",
"text": "Set or clear a password for saving this wiki"
},
"$:/language/Buttons/Encryption/ClearPassword/Caption": {
"title": "$:/language/Buttons/Encryption/ClearPassword/Caption",
"text": "clear password"
},
"$:/language/Buttons/Encryption/ClearPassword/Hint": {
"title": "$:/language/Buttons/Encryption/ClearPassword/Hint",
"text": "Clear the password and save this wiki without encryption"
},
"$:/language/Buttons/Encryption/SetPassword/Caption": {
"title": "$:/language/Buttons/Encryption/SetPassword/Caption",
"text": "set password"
},
"$:/language/Buttons/Encryption/SetPassword/Hint": {
"title": "$:/language/Buttons/Encryption/SetPassword/Hint",
"text": "Set a password for saving this wiki with encryption"
},
"$:/language/Buttons/ExportPage/Caption": {
"title": "$:/language/Buttons/ExportPage/Caption",
"text": "export all"
},
"$:/language/Buttons/ExportPage/Hint": {
"title": "$:/language/Buttons/ExportPage/Hint",
"text": "Export all tiddlers"
},
"$:/language/Buttons/ExportTiddler/Caption": {
"title": "$:/language/Buttons/ExportTiddler/Caption",
"text": "export tiddler"
},
"$:/language/Buttons/ExportTiddler/Hint": {
"title": "$:/language/Buttons/ExportTiddler/Hint",
"text": "Export tiddler"
},
"$:/language/Buttons/ExportTiddlers/Caption": {
"title": "$:/language/Buttons/ExportTiddlers/Caption",
"text": "export tiddlers"
},
"$:/language/Buttons/ExportTiddlers/Hint": {
"title": "$:/language/Buttons/ExportTiddlers/Hint",
"text": "Export tiddlers"
},
"$:/language/Buttons/Fold/Caption": {
"title": "$:/language/Buttons/Fold/Caption",
"text": "fold tiddler"
},
"$:/language/Buttons/Fold/Hint": {
"title": "$:/language/Buttons/Fold/Hint",
"text": "Fold the body of this tiddler"
},
"$:/language/Buttons/Fold/FoldBar/Caption": {
"title": "$:/language/Buttons/Fold/FoldBar/Caption",
"text": "fold-bar"
},
"$:/language/Buttons/Fold/FoldBar/Hint": {
"title": "$:/language/Buttons/Fold/FoldBar/Hint",
"text": "Optional bars to fold and unfold tiddlers"
},
"$:/language/Buttons/Unfold/Caption": {
"title": "$:/language/Buttons/Unfold/Caption",
"text": "unfold tiddler"
},
"$:/language/Buttons/Unfold/Hint": {
"title": "$:/language/Buttons/Unfold/Hint",
"text": "Unfold the body of this tiddler"
},
"$:/language/Buttons/FoldOthers/Caption": {
"title": "$:/language/Buttons/FoldOthers/Caption",
"text": "fold other tiddlers"
},
"$:/language/Buttons/FoldOthers/Hint": {
"title": "$:/language/Buttons/FoldOthers/Hint",
"text": "Fold the bodies of other opened tiddlers"
},
"$:/language/Buttons/FoldAll/Caption": {
"title": "$:/language/Buttons/FoldAll/Caption",
"text": "fold all tiddlers"
},
"$:/language/Buttons/FoldAll/Hint": {
"title": "$:/language/Buttons/FoldAll/Hint",
"text": "Fold the bodies of all opened tiddlers"
},
"$:/language/Buttons/UnfoldAll/Caption": {
"title": "$:/language/Buttons/UnfoldAll/Caption",
"text": "unfold all tiddlers"
},
"$:/language/Buttons/UnfoldAll/Hint": {
"title": "$:/language/Buttons/UnfoldAll/Hint",
"text": "Unfold the bodies of all opened tiddlers"
},
"$:/language/Buttons/FullScreen/Caption": {
"title": "$:/language/Buttons/FullScreen/Caption",
"text": "full-screen"
},
"$:/language/Buttons/FullScreen/Hint": {
"title": "$:/language/Buttons/FullScreen/Hint",
"text": "Enter or leave full-screen mode"
},
"$:/language/Buttons/Help/Caption": {
"title": "$:/language/Buttons/Help/Caption",
"text": "help"
},
"$:/language/Buttons/Help/Hint": {
"title": "$:/language/Buttons/Help/Hint",
"text": "Show help panel"
},
"$:/language/Buttons/Import/Caption": {
"title": "$:/language/Buttons/Import/Caption",
"text": "import"
},
"$:/language/Buttons/Import/Hint": {
"title": "$:/language/Buttons/Import/Hint",
"text": "Import many types of file including text, image, TiddlyWiki or JSON"
},
"$:/language/Buttons/Info/Caption": {
"title": "$:/language/Buttons/Info/Caption",
"text": "info"
},
"$:/language/Buttons/Info/Hint": {
"title": "$:/language/Buttons/Info/Hint",
"text": "Show information for this tiddler"
},
"$:/language/Buttons/Home/Caption": {
"title": "$:/language/Buttons/Home/Caption",
"text": "home"
},
"$:/language/Buttons/Home/Hint": {
"title": "$:/language/Buttons/Home/Hint",
"text": "Open the default tiddlers"
},
"$:/language/Buttons/Language/Caption": {
"title": "$:/language/Buttons/Language/Caption",
"text": "language"
},
"$:/language/Buttons/Language/Hint": {
"title": "$:/language/Buttons/Language/Hint",
"text": "Choose the user interface language"
},
"$:/language/Buttons/Manager/Caption": {
"title": "$:/language/Buttons/Manager/Caption",
"text": "tiddler manager"
},
"$:/language/Buttons/Manager/Hint": {
"title": "$:/language/Buttons/Manager/Hint",
"text": "Open tiddler manager"
},
"$:/language/Buttons/More/Caption": {
"title": "$:/language/Buttons/More/Caption",
"text": "more"
},
"$:/language/Buttons/More/Hint": {
"title": "$:/language/Buttons/More/Hint",
"text": "More actions"
},
"$:/language/Buttons/NewHere/Caption": {
"title": "$:/language/Buttons/NewHere/Caption",
"text": "new here"
},
"$:/language/Buttons/NewHere/Hint": {
"title": "$:/language/Buttons/NewHere/Hint",
"text": "Create a new tiddler tagged with this one"
},
"$:/language/Buttons/NewJournal/Caption": {
"title": "$:/language/Buttons/NewJournal/Caption",
"text": "new journal"
},
"$:/language/Buttons/NewJournal/Hint": {
"title": "$:/language/Buttons/NewJournal/Hint",
"text": "Create a new journal tiddler"
},
"$:/language/Buttons/NewJournalHere/Caption": {
"title": "$:/language/Buttons/NewJournalHere/Caption",
"text": "new journal here"
},
"$:/language/Buttons/NewJournalHere/Hint": {
"title": "$:/language/Buttons/NewJournalHere/Hint",
"text": "Create a new journal tiddler tagged with this one"
},
"$:/language/Buttons/NewImage/Caption": {
"title": "$:/language/Buttons/NewImage/Caption",
"text": "new image"
},
"$:/language/Buttons/NewImage/Hint": {
"title": "$:/language/Buttons/NewImage/Hint",
"text": "Create a new image tiddler"
},
"$:/language/Buttons/NewMarkdown/Caption": {
"title": "$:/language/Buttons/NewMarkdown/Caption",
"text": "new Markdown tiddler"
},
"$:/language/Buttons/NewMarkdown/Hint": {
"title": "$:/language/Buttons/NewMarkdown/Hint",
"text": "Create a new Markdown tiddler"
},
"$:/language/Buttons/NewTiddler/Caption": {
"title": "$:/language/Buttons/NewTiddler/Caption",
"text": "new tiddler"
},
"$:/language/Buttons/NewTiddler/Hint": {
"title": "$:/language/Buttons/NewTiddler/Hint",
"text": "Create a new tiddler"
},
"$:/language/Buttons/OpenWindow/Caption": {
"title": "$:/language/Buttons/OpenWindow/Caption",
"text": "open in new window"
},
"$:/language/Buttons/OpenWindow/Hint": {
"title": "$:/language/Buttons/OpenWindow/Hint",
"text": "Open tiddler in new window"
},
"$:/language/Buttons/Palette/Caption": {
"title": "$:/language/Buttons/Palette/Caption",
"text": "palette"
},
"$:/language/Buttons/Palette/Hint": {
"title": "$:/language/Buttons/Palette/Hint",
"text": "Choose the colour palette"
},
"$:/language/Buttons/Permalink/Caption": {
"title": "$:/language/Buttons/Permalink/Caption",
"text": "permalink"
},
"$:/language/Buttons/Permalink/Hint": {
"title": "$:/language/Buttons/Permalink/Hint",
"text": "Set browser address bar to a direct link to this tiddler"
},
"$:/language/Buttons/Permaview/Caption": {
"title": "$:/language/Buttons/Permaview/Caption",
"text": "permaview"
},
"$:/language/Buttons/Permaview/Hint": {
"title": "$:/language/Buttons/Permaview/Hint",
"text": "Set browser address bar to a direct link to all the tiddlers in this story"
},
"$:/language/Buttons/Print/Caption": {
"title": "$:/language/Buttons/Print/Caption",
"text": "print page"
},
"$:/language/Buttons/Print/Hint": {
"title": "$:/language/Buttons/Print/Hint",
"text": "Print the current page"
},
"$:/language/Buttons/Refresh/Caption": {
"title": "$:/language/Buttons/Refresh/Caption",
"text": "refresh"
},
"$:/language/Buttons/Refresh/Hint": {
"title": "$:/language/Buttons/Refresh/Hint",
"text": "Perform a full refresh of the wiki"
},
"$:/language/Buttons/Save/Caption": {
"title": "$:/language/Buttons/Save/Caption",
"text": "ok"
},
"$:/language/Buttons/Save/Hint": {
"title": "$:/language/Buttons/Save/Hint",
"text": "Confirm changes to this tiddler"
},
"$:/language/Buttons/SaveWiki/Caption": {
"title": "$:/language/Buttons/SaveWiki/Caption",
"text": "save changes"
},
"$:/language/Buttons/SaveWiki/Hint": {
"title": "$:/language/Buttons/SaveWiki/Hint",
"text": "Save changes"
},
"$:/language/Buttons/StoryView/Caption": {
"title": "$:/language/Buttons/StoryView/Caption",
"text": "storyview"
},
"$:/language/Buttons/StoryView/Hint": {
"title": "$:/language/Buttons/StoryView/Hint",
"text": "Choose the story visualisation"
},
"$:/language/Buttons/HideSideBar/Caption": {
"title": "$:/language/Buttons/HideSideBar/Caption",
"text": "hide sidebar"
},
"$:/language/Buttons/HideSideBar/Hint": {
"title": "$:/language/Buttons/HideSideBar/Hint",
"text": "Hide sidebar"
},
"$:/language/Buttons/ShowSideBar/Caption": {
"title": "$:/language/Buttons/ShowSideBar/Caption",
"text": "show sidebar"
},
"$:/language/Buttons/ShowSideBar/Hint": {
"title": "$:/language/Buttons/ShowSideBar/Hint",
"text": "Show sidebar"
},
"$:/language/Buttons/TagManager/Caption": {
"title": "$:/language/Buttons/TagManager/Caption",
"text": "tag manager"
},
"$:/language/Buttons/TagManager/Hint": {
"title": "$:/language/Buttons/TagManager/Hint",
"text": "Open tag manager"
},
"$:/language/Buttons/Timestamp/Caption": {
"title": "$:/language/Buttons/Timestamp/Caption",
"text": "timestamps"
},
"$:/language/Buttons/Timestamp/Hint": {
"title": "$:/language/Buttons/Timestamp/Hint",
"text": "Choose whether modifications update timestamps"
},
"$:/language/Buttons/Timestamp/On/Caption": {
"title": "$:/language/Buttons/Timestamp/On/Caption",
"text": "timestamps are on"
},
"$:/language/Buttons/Timestamp/On/Hint": {
"title": "$:/language/Buttons/Timestamp/On/Hint",
"text": "Update timestamps when tiddlers are modified"
},
"$:/language/Buttons/Timestamp/Off/Caption": {
"title": "$:/language/Buttons/Timestamp/Off/Caption",
"text": "timestamps are off"
},
"$:/language/Buttons/Timestamp/Off/Hint": {
"title": "$:/language/Buttons/Timestamp/Off/Hint",
"text": "Don't update timestamps when tiddlers are modified"
},
"$:/language/Buttons/Theme/Caption": {
"title": "$:/language/Buttons/Theme/Caption",
"text": "theme"
},
"$:/language/Buttons/Theme/Hint": {
"title": "$:/language/Buttons/Theme/Hint",
"text": "Choose the display theme"
},
"$:/language/Buttons/Bold/Caption": {
"title": "$:/language/Buttons/Bold/Caption",
"text": "bold"
},
"$:/language/Buttons/Bold/Hint": {
"title": "$:/language/Buttons/Bold/Hint",
"text": "Apply bold formatting to selection"
},
"$:/language/Buttons/Clear/Caption": {
"title": "$:/language/Buttons/Clear/Caption",
"text": "clear"
},
"$:/language/Buttons/Clear/Hint": {
"title": "$:/language/Buttons/Clear/Hint",
"text": "Clear image to solid colour"
},
"$:/language/Buttons/EditorHeight/Caption": {
"title": "$:/language/Buttons/EditorHeight/Caption",
"text": "editor height"
},
"$:/language/Buttons/EditorHeight/Caption/Auto": {
"title": "$:/language/Buttons/EditorHeight/Caption/Auto",
"text": "Automatically adjust height to fit content"
},
"$:/language/Buttons/EditorHeight/Caption/Fixed": {
"title": "$:/language/Buttons/EditorHeight/Caption/Fixed",
"text": "Fixed height:"
},
"$:/language/Buttons/EditorHeight/Hint": {
"title": "$:/language/Buttons/EditorHeight/Hint",
"text": "Choose the height of the text editor"
},
"$:/language/Buttons/Excise/Caption": {
"title": "$:/language/Buttons/Excise/Caption",
"text": "excise"
},
"$:/language/Buttons/Excise/Caption/Excise": {
"title": "$:/language/Buttons/Excise/Caption/Excise",
"text": "Perform excision"
},
"$:/language/Buttons/Excise/Caption/MacroName": {
"title": "$:/language/Buttons/Excise/Caption/MacroName",
"text": "Macro name:"
},
"$:/language/Buttons/Excise/Caption/NewTitle": {
"title": "$:/language/Buttons/Excise/Caption/NewTitle",
"text": "Title of new tiddler:"
},
"$:/language/Buttons/Excise/Caption/Replace": {
"title": "$:/language/Buttons/Excise/Caption/Replace",
"text": "Replace excised text with:"
},
"$:/language/Buttons/Excise/Caption/Replace/Macro": {
"title": "$:/language/Buttons/Excise/Caption/Replace/Macro",
"text": "macro"
},
"$:/language/Buttons/Excise/Caption/Replace/Link": {
"title": "$:/language/Buttons/Excise/Caption/Replace/Link",
"text": "link"
},
"$:/language/Buttons/Excise/Caption/Replace/Transclusion": {
"title": "$:/language/Buttons/Excise/Caption/Replace/Transclusion",
"text": "transclusion"
},
"$:/language/Buttons/Excise/Caption/Tag": {
"title": "$:/language/Buttons/Excise/Caption/Tag",
"text": "Tag new tiddler with the title of this tiddler"
},
"$:/language/Buttons/Excise/Caption/TiddlerExists": {
"title": "$:/language/Buttons/Excise/Caption/TiddlerExists",
"text": "Warning: tiddler already exists"
},
"$:/language/Buttons/Excise/Hint": {
"title": "$:/language/Buttons/Excise/Hint",
"text": "Excise the selected text into a new tiddler"
},
"$:/language/Buttons/Heading1/Caption": {
"title": "$:/language/Buttons/Heading1/Caption",
"text": "heading 1"
},
"$:/language/Buttons/Heading1/Hint": {
"title": "$:/language/Buttons/Heading1/Hint",
"text": "Apply heading level 1 formatting to lines containing selection"
},
"$:/language/Buttons/Heading2/Caption": {
"title": "$:/language/Buttons/Heading2/Caption",
"text": "heading 2"
},
"$:/language/Buttons/Heading2/Hint": {
"title": "$:/language/Buttons/Heading2/Hint",
"text": "Apply heading level 2 formatting to lines containing selection"
},
"$:/language/Buttons/Heading3/Caption": {
"title": "$:/language/Buttons/Heading3/Caption",
"text": "heading 3"
},
"$:/language/Buttons/Heading3/Hint": {
"title": "$:/language/Buttons/Heading3/Hint",
"text": "Apply heading level 3 formatting to lines containing selection"
},
"$:/language/Buttons/Heading4/Caption": {
"title": "$:/language/Buttons/Heading4/Caption",
"text": "heading 4"
},
"$:/language/Buttons/Heading4/Hint": {
"title": "$:/language/Buttons/Heading4/Hint",
"text": "Apply heading level 4 formatting to lines containing selection"
},
"$:/language/Buttons/Heading5/Caption": {
"title": "$:/language/Buttons/Heading5/Caption",
"text": "heading 5"
},
"$:/language/Buttons/Heading5/Hint": {
"title": "$:/language/Buttons/Heading5/Hint",
"text": "Apply heading level 5 formatting to lines containing selection"
},
"$:/language/Buttons/Heading6/Caption": {
"title": "$:/language/Buttons/Heading6/Caption",
"text": "heading 6"
},
"$:/language/Buttons/Heading6/Hint": {
"title": "$:/language/Buttons/Heading6/Hint",
"text": "Apply heading level 6 formatting to lines containing selection"
},
"$:/language/Buttons/Italic/Caption": {
"title": "$:/language/Buttons/Italic/Caption",
"text": "italic"
},
"$:/language/Buttons/Italic/Hint": {
"title": "$:/language/Buttons/Italic/Hint",
"text": "Apply italic formatting to selection"
},
"$:/language/Buttons/LineWidth/Caption": {
"title": "$:/language/Buttons/LineWidth/Caption",
"text": "line width"
},
"$:/language/Buttons/LineWidth/Hint": {
"title": "$:/language/Buttons/LineWidth/Hint",
"text": "Set line width for painting"
},
"$:/language/Buttons/Link/Caption": {
"title": "$:/language/Buttons/Link/Caption",
"text": "link"
},
"$:/language/Buttons/Link/Hint": {
"title": "$:/language/Buttons/Link/Hint",
"text": "Create wikitext link"
},
"$:/language/Buttons/Linkify/Caption": {
"title": "$:/language/Buttons/Linkify/Caption",
"text": "wikilink"
},
"$:/language/Buttons/Linkify/Hint": {
"title": "$:/language/Buttons/Linkify/Hint",
"text": "Wrap selection in square brackets"
},
"$:/language/Buttons/ListBullet/Caption": {
"title": "$:/language/Buttons/ListBullet/Caption",
"text": "bulleted list"
},
"$:/language/Buttons/ListBullet/Hint": {
"title": "$:/language/Buttons/ListBullet/Hint",
"text": "Apply bulleted list formatting to lines containing selection"
},
"$:/language/Buttons/ListNumber/Caption": {
"title": "$:/language/Buttons/ListNumber/Caption",
"text": "numbered list"
},
"$:/language/Buttons/ListNumber/Hint": {
"title": "$:/language/Buttons/ListNumber/Hint",
"text": "Apply numbered list formatting to lines containing selection"
},
"$:/language/Buttons/MonoBlock/Caption": {
"title": "$:/language/Buttons/MonoBlock/Caption",
"text": "monospaced block"
},
"$:/language/Buttons/MonoBlock/Hint": {
"title": "$:/language/Buttons/MonoBlock/Hint",
"text": "Apply monospaced block formatting to lines containing selection"
},
"$:/language/Buttons/MonoLine/Caption": {
"title": "$:/language/Buttons/MonoLine/Caption",
"text": "monospaced"
},
"$:/language/Buttons/MonoLine/Hint": {
"title": "$:/language/Buttons/MonoLine/Hint",
"text": "Apply monospaced character formatting to selection"
},
"$:/language/Buttons/Opacity/Caption": {
"title": "$:/language/Buttons/Opacity/Caption",
"text": "opacity"
},
"$:/language/Buttons/Opacity/Hint": {
"title": "$:/language/Buttons/Opacity/Hint",
"text": "Set painting opacity"
},
"$:/language/Buttons/Paint/Caption": {
"title": "$:/language/Buttons/Paint/Caption",
"text": "paint colour"
},
"$:/language/Buttons/Paint/Hint": {
"title": "$:/language/Buttons/Paint/Hint",
"text": "Set painting colour"
},
"$:/language/Buttons/Picture/Caption": {
"title": "$:/language/Buttons/Picture/Caption",
"text": "picture"
},
"$:/language/Buttons/Picture/Hint": {
"title": "$:/language/Buttons/Picture/Hint",
"text": "Insert picture"
},
"$:/language/Buttons/Preview/Caption": {
"title": "$:/language/Buttons/Preview/Caption",
"text": "preview"
},
"$:/language/Buttons/Preview/Hint": {
"title": "$:/language/Buttons/Preview/Hint",
"text": "Show preview pane"
},
"$:/language/Buttons/PreviewType/Caption": {
"title": "$:/language/Buttons/PreviewType/Caption",
"text": "preview type"
},
"$:/language/Buttons/PreviewType/Hint": {
"title": "$:/language/Buttons/PreviewType/Hint",
"text": "Choose preview type"
},
"$:/language/Buttons/Quote/Caption": {
"title": "$:/language/Buttons/Quote/Caption",
"text": "quote"
},
"$:/language/Buttons/Quote/Hint": {
"title": "$:/language/Buttons/Quote/Hint",
"text": "Apply quoted text formatting to lines containing selection"
},
"$:/language/Buttons/RotateLeft/Caption": {
"title": "$:/language/Buttons/RotateLeft/Caption",
"text": "rotate left"
},
"$:/language/Buttons/RotateLeft/Hint": {
"title": "$:/language/Buttons/RotateLeft/Hint",
"text": "Rotate image left by 90 degrees"
},
"$:/language/Buttons/Size/Caption": {
"title": "$:/language/Buttons/Size/Caption",
"text": "image size"
},
"$:/language/Buttons/Size/Caption/Height": {
"title": "$:/language/Buttons/Size/Caption/Height",
"text": "Height:"
},
"$:/language/Buttons/Size/Caption/Resize": {
"title": "$:/language/Buttons/Size/Caption/Resize",
"text": "Resize image"
},
"$:/language/Buttons/Size/Caption/Width": {
"title": "$:/language/Buttons/Size/Caption/Width",
"text": "Width:"
},
"$:/language/Buttons/Size/Hint": {
"title": "$:/language/Buttons/Size/Hint",
"text": "Set image size"
},
"$:/language/Buttons/Stamp/Caption": {
"title": "$:/language/Buttons/Stamp/Caption",
"text": "stamp"
},
"$:/language/Buttons/Stamp/Caption/New": {
"title": "$:/language/Buttons/Stamp/Caption/New",
"text": "Add your own"
},
"$:/language/Buttons/Stamp/Hint": {
"title": "$:/language/Buttons/Stamp/Hint",
"text": "Insert a preconfigured snippet of text"
},
"$:/language/Buttons/Stamp/New/Title": {
"title": "$:/language/Buttons/Stamp/New/Title",
"text": "Name as shown in menu"
},
"$:/language/Buttons/Stamp/New/Text": {
"title": "$:/language/Buttons/Stamp/New/Text",
"text": "Text of snippet. (Remember to add a descriptive title in the caption field)."
},
"$:/language/Buttons/Strikethrough/Caption": {
"title": "$:/language/Buttons/Strikethrough/Caption",
"text": "strikethrough"
},
"$:/language/Buttons/Strikethrough/Hint": {
"title": "$:/language/Buttons/Strikethrough/Hint",
"text": "Apply strikethrough formatting to selection"
},
"$:/language/Buttons/Subscript/Caption": {
"title": "$:/language/Buttons/Subscript/Caption",
"text": "subscript"
},
"$:/language/Buttons/Subscript/Hint": {
"title": "$:/language/Buttons/Subscript/Hint",
"text": "Apply subscript formatting to selection"
},
"$:/language/Buttons/Superscript/Caption": {
"title": "$:/language/Buttons/Superscript/Caption",
"text": "superscript"
},
"$:/language/Buttons/Superscript/Hint": {
"title": "$:/language/Buttons/Superscript/Hint",
"text": "Apply superscript formatting to selection"
},
"$:/language/Buttons/Transcludify/Caption": {
"title": "$:/language/Buttons/Transcludify/Caption",
"text": "transclusion"
},
"$:/language/Buttons/Transcludify/Hint": {
"title": "$:/language/Buttons/Transcludify/Hint",
"text": "Wrap selection in curly brackets"
},
"$:/language/Buttons/Underline/Caption": {
"title": "$:/language/Buttons/Underline/Caption",
"text": "underline"
},
"$:/language/Buttons/Underline/Hint": {
"title": "$:/language/Buttons/Underline/Hint",
"text": "Apply underline formatting to selection"
},
"$:/language/ControlPanel/Advanced/Caption": {
"title": "$:/language/ControlPanel/Advanced/Caption",
"text": "Advanced"
},
"$:/language/ControlPanel/Advanced/Hint": {
"title": "$:/language/ControlPanel/Advanced/Hint",
"text": "Internal information about this TiddlyWiki"
},
"$:/language/ControlPanel/Appearance/Caption": {
"title": "$:/language/ControlPanel/Appearance/Caption",
"text": "Appearance"
},
"$:/language/ControlPanel/Appearance/Hint": {
"title": "$:/language/ControlPanel/Appearance/Hint",
"text": "Ways to customise the appearance of your TiddlyWiki."
},
"$:/language/ControlPanel/Basics/AnimDuration/Prompt": {
"title": "$:/language/ControlPanel/Basics/AnimDuration/Prompt",
"text": "Animation duration:"
},
"$:/language/ControlPanel/Basics/Caption": {
"title": "$:/language/ControlPanel/Basics/Caption",
"text": "Basics"
},
"$:/language/ControlPanel/Basics/DefaultTiddlers/BottomHint": {
"title": "$:/language/ControlPanel/Basics/DefaultTiddlers/BottomHint",
"text": "Use [[double square brackets]] for titles with spaces. Or you can choose to <$button set=\"$:/DefaultTiddlers\" setTo=\"[list[$:/StoryList]]\">retain story ordering</$button>"
},
"$:/language/ControlPanel/Basics/DefaultTiddlers/Prompt": {
"title": "$:/language/ControlPanel/Basics/DefaultTiddlers/Prompt",
"text": "Default tiddlers:"
},
"$:/language/ControlPanel/Basics/DefaultTiddlers/TopHint": {
"title": "$:/language/ControlPanel/Basics/DefaultTiddlers/TopHint",
"text": "Choose which tiddlers are displayed at startup:"
},
"$:/language/ControlPanel/Basics/Language/Prompt": {
"title": "$:/language/ControlPanel/Basics/Language/Prompt",
"text": "Hello! Current language:"
},
"$:/language/ControlPanel/Basics/NewJournal/Title/Prompt": {
"title": "$:/language/ControlPanel/Basics/NewJournal/Title/Prompt",
"text": "Title of new journal tiddlers"
},
"$:/language/ControlPanel/Basics/NewJournal/Text/Prompt": {
"title": "$:/language/ControlPanel/Basics/NewJournal/Text/Prompt",
"text": "Text for new journal tiddlers"
},
"$:/language/ControlPanel/Basics/NewJournal/Tags/Prompt": {
"title": "$:/language/ControlPanel/Basics/NewJournal/Tags/Prompt",
"text": "Tags for new journal tiddlers"
},
"$:/language/ControlPanel/Basics/NewTiddler/Title/Prompt": {
"title": "$:/language/ControlPanel/Basics/NewTiddler/Title/Prompt",
"text": "Title of new tiddlers"
},
"$:/language/ControlPanel/Basics/OverriddenShadowTiddlers/Prompt": {
"title": "$:/language/ControlPanel/Basics/OverriddenShadowTiddlers/Prompt",
"text": "Number of overridden shadow tiddlers:"
},
"$:/language/ControlPanel/Basics/ShadowTiddlers/Prompt": {
"title": "$:/language/ControlPanel/Basics/ShadowTiddlers/Prompt",
"text": "Number of shadow tiddlers:"
},
"$:/language/ControlPanel/Basics/Subtitle/Prompt": {
"title": "$:/language/ControlPanel/Basics/Subtitle/Prompt",
"text": "Subtitle:"
},
"$:/language/ControlPanel/Basics/SystemTiddlers/Prompt": {
"title": "$:/language/ControlPanel/Basics/SystemTiddlers/Prompt",
"text": "Number of system tiddlers:"
},
"$:/language/ControlPanel/Basics/Tags/Prompt": {
"title": "$:/language/ControlPanel/Basics/Tags/Prompt",
"text": "Number of tags:"
},
"$:/language/ControlPanel/Basics/Tiddlers/Prompt": {
"title": "$:/language/ControlPanel/Basics/Tiddlers/Prompt",
"text": "Number of tiddlers:"
},
"$:/language/ControlPanel/Basics/Title/Prompt": {
"title": "$:/language/ControlPanel/Basics/Title/Prompt",
"text": "Title of this ~TiddlyWiki:"
},
"$:/language/ControlPanel/Basics/Username/Prompt": {
"title": "$:/language/ControlPanel/Basics/Username/Prompt",
"text": "Username for signing edits:"
},
"$:/language/ControlPanel/Basics/Version/Prompt": {
"title": "$:/language/ControlPanel/Basics/Version/Prompt",
"text": "~TiddlyWiki version:"
},
"$:/language/ControlPanel/EditorTypes/Caption": {
"title": "$:/language/ControlPanel/EditorTypes/Caption",
"text": "Editor Types"
},
"$:/language/ControlPanel/EditorTypes/Editor/Caption": {
"title": "$:/language/ControlPanel/EditorTypes/Editor/Caption",
"text": "Editor"
},
"$:/language/ControlPanel/EditorTypes/Hint": {
"title": "$:/language/ControlPanel/EditorTypes/Hint",
"text": "These tiddlers determine which editor is used to edit specific tiddler types."
},
"$:/language/ControlPanel/EditorTypes/Type/Caption": {
"title": "$:/language/ControlPanel/EditorTypes/Type/Caption",
"text": "Type"
},
"$:/language/ControlPanel/Info/Caption": {
"title": "$:/language/ControlPanel/Info/Caption",
"text": "Info"
},
"$:/language/ControlPanel/Info/Hint": {
"title": "$:/language/ControlPanel/Info/Hint",
"text": "Information about this TiddlyWiki"
},
"$:/language/ControlPanel/KeyboardShortcuts/Add/Prompt": {
"title": "$:/language/ControlPanel/KeyboardShortcuts/Add/Prompt",
"text": "Type shortcut here"
},
"$:/language/ControlPanel/KeyboardShortcuts/Add/Caption": {
"title": "$:/language/ControlPanel/KeyboardShortcuts/Add/Caption",
"text": "add shortcut"
},
"$:/language/ControlPanel/KeyboardShortcuts/Caption": {
"title": "$:/language/ControlPanel/KeyboardShortcuts/Caption",
"text": "Keyboard Shortcuts"
},
"$:/language/ControlPanel/KeyboardShortcuts/Hint": {
"title": "$:/language/ControlPanel/KeyboardShortcuts/Hint",
"text": "Manage keyboard shortcut assignments"
},
"$:/language/ControlPanel/KeyboardShortcuts/NoShortcuts/Caption": {
"title": "$:/language/ControlPanel/KeyboardShortcuts/NoShortcuts/Caption",
"text": "No keyboard shortcuts assigned"
},
"$:/language/ControlPanel/KeyboardShortcuts/Remove/Hint": {
"title": "$:/language/ControlPanel/KeyboardShortcuts/Remove/Hint",
"text": "remove keyboard shortcut"
},
"$:/language/ControlPanel/KeyboardShortcuts/Platform/All": {
"title": "$:/language/ControlPanel/KeyboardShortcuts/Platform/All",
"text": "All platforms"
},
"$:/language/ControlPanel/KeyboardShortcuts/Platform/Mac": {
"title": "$:/language/ControlPanel/KeyboardShortcuts/Platform/Mac",
"text": "Macintosh platform only"
},
"$:/language/ControlPanel/KeyboardShortcuts/Platform/NonMac": {
"title": "$:/language/ControlPanel/KeyboardShortcuts/Platform/NonMac",
"text": "Non-Macintosh platforms only"
},
"$:/language/ControlPanel/KeyboardShortcuts/Platform/Linux": {
"title": "$:/language/ControlPanel/KeyboardShortcuts/Platform/Linux",
"text": "Linux platform only"
},
"$:/language/ControlPanel/KeyboardShortcuts/Platform/NonLinux": {
"title": "$:/language/ControlPanel/KeyboardShortcuts/Platform/NonLinux",
"text": "Non-Linux platforms only"
},
"$:/language/ControlPanel/KeyboardShortcuts/Platform/Windows": {
"title": "$:/language/ControlPanel/KeyboardShortcuts/Platform/Windows",
"text": "Windows platform only"
},
"$:/language/ControlPanel/KeyboardShortcuts/Platform/NonWindows": {
"title": "$:/language/ControlPanel/KeyboardShortcuts/Platform/NonWindows",
"text": "Non-Windows platforms only"
},
"$:/language/ControlPanel/LoadedModules/Caption": {
"title": "$:/language/ControlPanel/LoadedModules/Caption",
"text": "Loaded Modules"
},
"$:/language/ControlPanel/LoadedModules/Hint": {
"title": "$:/language/ControlPanel/LoadedModules/Hint",
"text": "These are the currently loaded tiddler modules linked to their source tiddlers. Any italicised modules lack a source tiddler, typically because they were setup during the boot process."
},
"$:/language/ControlPanel/Palette/Caption": {
"title": "$:/language/ControlPanel/Palette/Caption",
"text": "Palette"
},
"$:/language/ControlPanel/Palette/Editor/Clone/Caption": {
"title": "$:/language/ControlPanel/Palette/Editor/Clone/Caption",
"text": "clone"
},
"$:/language/ControlPanel/Palette/Editor/Clone/Prompt": {
"title": "$:/language/ControlPanel/Palette/Editor/Clone/Prompt",
"text": "It is recommended that you clone this shadow palette before editing it"
},
"$:/language/ControlPanel/Palette/Editor/Prompt/Modified": {
"title": "$:/language/ControlPanel/Palette/Editor/Prompt/Modified",
"text": "This shadow palette has been modified"
},
"$:/language/ControlPanel/Palette/Editor/Prompt": {
"title": "$:/language/ControlPanel/Palette/Editor/Prompt",
"text": "Editing"
},
"$:/language/ControlPanel/Palette/Editor/Reset/Caption": {
"title": "$:/language/ControlPanel/Palette/Editor/Reset/Caption",
"text": "reset"
},
"$:/language/ControlPanel/Palette/HideEditor/Caption": {
"title": "$:/language/ControlPanel/Palette/HideEditor/Caption",
"text": "hide editor"
},
"$:/language/ControlPanel/Palette/Prompt": {
"title": "$:/language/ControlPanel/Palette/Prompt",
"text": "Current palette:"
},
"$:/language/ControlPanel/Palette/ShowEditor/Caption": {
"title": "$:/language/ControlPanel/Palette/ShowEditor/Caption",
"text": "show editor"
},
"$:/language/ControlPanel/Parsing/Caption": {
"title": "$:/language/ControlPanel/Parsing/Caption",
"text": "Parsing"
},
"$:/language/ControlPanel/Parsing/Hint": {
"title": "$:/language/ControlPanel/Parsing/Hint",
"text": "Here you can globally disable/enable wiki parser rules. For changes to take effect, save and reload your wiki. Disabling certain parser rules can prevent <$text text=\"TiddlyWiki\"/> from functioning correctly. Use [[safe mode|https://tiddlywiki.com/#SafeMode]] to restore normal operation."
},
"$:/language/ControlPanel/Parsing/Block/Caption": {
"title": "$:/language/ControlPanel/Parsing/Block/Caption",
"text": "Block Parse Rules"
},
"$:/language/ControlPanel/Parsing/Inline/Caption": {
"title": "$:/language/ControlPanel/Parsing/Inline/Caption",
"text": "Inline Parse Rules"
},
"$:/language/ControlPanel/Parsing/Pragma/Caption": {
"title": "$:/language/ControlPanel/Parsing/Pragma/Caption",
"text": "Pragma Parse Rules"
},
"$:/language/ControlPanel/Plugins/Add/Caption": {
"title": "$:/language/ControlPanel/Plugins/Add/Caption",
"text": "Get more plugins"
},
"$:/language/ControlPanel/Plugins/Add/Hint": {
"title": "$:/language/ControlPanel/Plugins/Add/Hint",
"text": "Install plugins from the official library"
},
"$:/language/ControlPanel/Plugins/AlreadyInstalled/Hint": {
"title": "$:/language/ControlPanel/Plugins/AlreadyInstalled/Hint",
"text": "This plugin is already installed at version <$text text=<<installedVersion>>/>"
},
"$:/language/ControlPanel/Plugins/Caption": {
"title": "$:/language/ControlPanel/Plugins/Caption",
"text": "Plugins"
},
"$:/language/ControlPanel/Plugins/Disable/Caption": {
"title": "$:/language/ControlPanel/Plugins/Disable/Caption",
"text": "disable"
},
"$:/language/ControlPanel/Plugins/Disable/Hint": {
"title": "$:/language/ControlPanel/Plugins/Disable/Hint",
"text": "Disable this plugin when reloading page"
},
"$:/language/ControlPanel/Plugins/Disabled/Status": {
"title": "$:/language/ControlPanel/Plugins/Disabled/Status",
"text": "(disabled)"
},
"$:/language/ControlPanel/Plugins/Empty/Hint": {
"title": "$:/language/ControlPanel/Plugins/Empty/Hint",
"text": "None"
},
"$:/language/ControlPanel/Plugins/Enable/Caption": {
"title": "$:/language/ControlPanel/Plugins/Enable/Caption",
"text": "enable"
},
"$:/language/ControlPanel/Plugins/Enable/Hint": {
"title": "$:/language/ControlPanel/Plugins/Enable/Hint",
"text": "Enable this plugin when reloading page"
},
"$:/language/ControlPanel/Plugins/Install/Caption": {
"title": "$:/language/ControlPanel/Plugins/Install/Caption",
"text": "install"
},
"$:/language/ControlPanel/Plugins/Installed/Hint": {
"title": "$:/language/ControlPanel/Plugins/Installed/Hint",
"text": "Currently installed plugins:"
},
"$:/language/ControlPanel/Plugins/Languages/Caption": {
"title": "$:/language/ControlPanel/Plugins/Languages/Caption",
"text": "Languages"
},
"$:/language/ControlPanel/Plugins/Languages/Hint": {
"title": "$:/language/ControlPanel/Plugins/Languages/Hint",
"text": "Language pack plugins"
},
"$:/language/ControlPanel/Plugins/NoInfoFound/Hint": {
"title": "$:/language/ControlPanel/Plugins/NoInfoFound/Hint",
"text": "No ''\"<$text text=<<currentTab>>/>\"'' found"
},
"$:/language/ControlPanel/Plugins/NotInstalled/Hint": {
"title": "$:/language/ControlPanel/Plugins/NotInstalled/Hint",
"text": "This plugin is not currently installed"
},
"$:/language/ControlPanel/Plugins/OpenPluginLibrary": {
"title": "$:/language/ControlPanel/Plugins/OpenPluginLibrary",
"text": "open plugin library"
},
"$:/language/ControlPanel/Plugins/ClosePluginLibrary": {
"title": "$:/language/ControlPanel/Plugins/ClosePluginLibrary",
"text": "close plugin library"
},
"$:/language/ControlPanel/Plugins/Plugins/Caption": {
"title": "$:/language/ControlPanel/Plugins/Plugins/Caption",
"text": "Plugins"
},
"$:/language/ControlPanel/Plugins/Plugins/Hint": {
"title": "$:/language/ControlPanel/Plugins/Plugins/Hint",
"text": "Plugins"
},
"$:/language/ControlPanel/Plugins/Reinstall/Caption": {
"title": "$:/language/ControlPanel/Plugins/Reinstall/Caption",
"text": "reinstall"
},
"$:/language/ControlPanel/Plugins/Themes/Caption": {
"title": "$:/language/ControlPanel/Plugins/Themes/Caption",
"text": "Themes"
},
"$:/language/ControlPanel/Plugins/Themes/Hint": {
"title": "$:/language/ControlPanel/Plugins/Themes/Hint",
"text": "Theme plugins"
},
"$:/language/ControlPanel/Saving/Caption": {
"title": "$:/language/ControlPanel/Saving/Caption",
"text": "Saving"
},
"$:/language/ControlPanel/Saving/DownloadSaver/AutoSave/Description": {
"title": "$:/language/ControlPanel/Saving/DownloadSaver/AutoSave/Description",
"text": "Permit automatic saving for the download saver"
},
"$:/language/ControlPanel/Saving/DownloadSaver/AutoSave/Hint": {
"title": "$:/language/ControlPanel/Saving/DownloadSaver/AutoSave/Hint",
"text": "Enable Autosave for Download Saver"
},
"$:/language/ControlPanel/Saving/DownloadSaver/Caption": {
"title": "$:/language/ControlPanel/Saving/DownloadSaver/Caption",
"text": "Download Saver"
},
"$:/language/ControlPanel/Saving/DownloadSaver/Hint": {
"title": "$:/language/ControlPanel/Saving/DownloadSaver/Hint",
"text": "These settings apply to the HTML5-compatible download saver"
},
"$:/language/ControlPanel/Saving/General/Caption": {
"title": "$:/language/ControlPanel/Saving/General/Caption",
"text": "General"
},
"$:/language/ControlPanel/Saving/General/Hint": {
"title": "$:/language/ControlPanel/Saving/General/Hint",
"text": "These settings apply to all the loaded savers"
},
"$:/language/ControlPanel/Saving/Hint": {
"title": "$:/language/ControlPanel/Saving/Hint",
"text": "Settings used for saving the entire TiddlyWiki as a single file via a saver module"
},
"$:/language/ControlPanel/Saving/TiddlySpot/Advanced/Heading": {
"title": "$:/language/ControlPanel/Saving/TiddlySpot/Advanced/Heading",
"text": "Advanced Settings"
},
"$:/language/ControlPanel/Saving/TiddlySpot/BackupDir": {
"title": "$:/language/ControlPanel/Saving/TiddlySpot/BackupDir",
"text": "Backup Directory"
},
"$:/language/ControlPanel/Saving/TiddlySpot/Backups": {
"title": "$:/language/ControlPanel/Saving/TiddlySpot/Backups",
"text": "Backups"
},
"$:/language/ControlPanel/Saving/TiddlySpot/Caption": {
"title": "$:/language/ControlPanel/Saving/TiddlySpot/Caption",
"text": "~TiddlySpot Saver"
},
"$:/language/ControlPanel/Saving/TiddlySpot/Description": {
"title": "$:/language/ControlPanel/Saving/TiddlySpot/Description",
"text": "These settings are only used when saving to http://tiddlyspot.com or a compatible remote server"
},
"$:/language/ControlPanel/Saving/TiddlySpot/Filename": {
"title": "$:/language/ControlPanel/Saving/TiddlySpot/Filename",
"text": "Upload Filename"
},
"$:/language/ControlPanel/Saving/TiddlySpot/Heading": {
"title": "$:/language/ControlPanel/Saving/TiddlySpot/Heading",
"text": "~TiddlySpot"
},
"$:/language/ControlPanel/Saving/TiddlySpot/Hint": {
"title": "$:/language/ControlPanel/Saving/TiddlySpot/Hint",
"text": "//The server URL defaults to `http://<wikiname>.tiddlyspot.com/store.cgi` and can be changed to use a custom server address, e.g. `http://example.com/store.php`.//"
},
"$:/language/ControlPanel/Saving/TiddlySpot/Password": {
"title": "$:/language/ControlPanel/Saving/TiddlySpot/Password",
"text": "Password"
},
"$:/language/ControlPanel/Saving/TiddlySpot/ServerURL": {
"title": "$:/language/ControlPanel/Saving/TiddlySpot/ServerURL",
"text": "Server URL"
},
"$:/language/ControlPanel/Saving/TiddlySpot/UploadDir": {
"title": "$:/language/ControlPanel/Saving/TiddlySpot/UploadDir",
"text": "Upload Directory"
},
"$:/language/ControlPanel/Saving/TiddlySpot/UserName": {
"title": "$:/language/ControlPanel/Saving/TiddlySpot/UserName",
"text": "Wiki Name"
},
"$:/language/ControlPanel/Settings/AutoSave/Caption": {
"title": "$:/language/ControlPanel/Settings/AutoSave/Caption",
"text": "Autosave"
},
"$:/language/ControlPanel/Settings/AutoSave/Disabled/Description": {
"title": "$:/language/ControlPanel/Settings/AutoSave/Disabled/Description",
"text": "Do not save changes automatically"
},
"$:/language/ControlPanel/Settings/AutoSave/Enabled/Description": {
"title": "$:/language/ControlPanel/Settings/AutoSave/Enabled/Description",
"text": "Save changes automatically"
},
"$:/language/ControlPanel/Settings/AutoSave/Hint": {
"title": "$:/language/ControlPanel/Settings/AutoSave/Hint",
"text": "Attempt to automatically save changes during editing when using a supporting saver"
},
"$:/language/ControlPanel/Settings/CamelCase/Caption": {
"title": "$:/language/ControlPanel/Settings/CamelCase/Caption",
"text": "Camel Case Wiki Links"
},
"$:/language/ControlPanel/Settings/CamelCase/Hint": {
"title": "$:/language/ControlPanel/Settings/CamelCase/Hint",
"text": "You can globally disable automatic linking of ~CamelCase phrases. Requires reload to take effect"
},
"$:/language/ControlPanel/Settings/CamelCase/Description": {
"title": "$:/language/ControlPanel/Settings/CamelCase/Description",
"text": "Enable automatic ~CamelCase linking"
},
"$:/language/ControlPanel/Settings/Caption": {
"title": "$:/language/ControlPanel/Settings/Caption",
"text": "Settings"
},
"$:/language/ControlPanel/Settings/EditorToolbar/Caption": {
"title": "$:/language/ControlPanel/Settings/EditorToolbar/Caption",
"text": "Editor Toolbar"
},
"$:/language/ControlPanel/Settings/EditorToolbar/Hint": {
"title": "$:/language/ControlPanel/Settings/EditorToolbar/Hint",
"text": "Enable or disable the editor toolbar:"
},
"$:/language/ControlPanel/Settings/EditorToolbar/Description": {
"title": "$:/language/ControlPanel/Settings/EditorToolbar/Description",
"text": "Show editor toolbar"
},
"$:/language/ControlPanel/Settings/InfoPanelMode/Caption": {
"title": "$:/language/ControlPanel/Settings/InfoPanelMode/Caption",
"text": "Tiddler Info Panel Mode"
},
"$:/language/ControlPanel/Settings/InfoPanelMode/Hint": {
"title": "$:/language/ControlPanel/Settings/InfoPanelMode/Hint",
"text": "Control when the tiddler info panel closes:"
},
"$:/language/ControlPanel/Settings/InfoPanelMode/Popup/Description": {
"title": "$:/language/ControlPanel/Settings/InfoPanelMode/Popup/Description",
"text": "Tiddler info panel closes automatically"
},
"$:/language/ControlPanel/Settings/InfoPanelMode/Sticky/Description": {
"title": "$:/language/ControlPanel/Settings/InfoPanelMode/Sticky/Description",
"text": "Tiddler info panel stays open until explicitly closed"
},
"$:/language/ControlPanel/Settings/Hint": {
"title": "$:/language/ControlPanel/Settings/Hint",
"text": "These settings let you customise the behaviour of TiddlyWiki."
},
"$:/language/ControlPanel/Settings/NavigationAddressBar/Caption": {
"title": "$:/language/ControlPanel/Settings/NavigationAddressBar/Caption",
"text": "Navigation Address Bar"
},
"$:/language/ControlPanel/Settings/NavigationAddressBar/Hint": {
"title": "$:/language/ControlPanel/Settings/NavigationAddressBar/Hint",
"text": "Behaviour of the browser address bar when navigating to a tiddler:"
},
"$:/language/ControlPanel/Settings/NavigationAddressBar/No/Description": {
"title": "$:/language/ControlPanel/Settings/NavigationAddressBar/No/Description",
"text": "Do not update the address bar"
},
"$:/language/ControlPanel/Settings/NavigationAddressBar/Permalink/Description": {
"title": "$:/language/ControlPanel/Settings/NavigationAddressBar/Permalink/Description",
"text": "Include the target tiddler"
},
"$:/language/ControlPanel/Settings/NavigationAddressBar/Permaview/Description": {
"title": "$:/language/ControlPanel/Settings/NavigationAddressBar/Permaview/Description",
"text": "Include the target tiddler and the current story sequence"
},
"$:/language/ControlPanel/Settings/NavigationHistory/Caption": {
"title": "$:/language/ControlPanel/Settings/NavigationHistory/Caption",
"text": "Navigation History"
},
"$:/language/ControlPanel/Settings/NavigationHistory/Hint": {
"title": "$:/language/ControlPanel/Settings/NavigationHistory/Hint",
"text": "Update browser history when navigating to a tiddler:"
},
"$:/language/ControlPanel/Settings/NavigationHistory/No/Description": {
"title": "$:/language/ControlPanel/Settings/NavigationHistory/No/Description",
"text": "Do not update history"
},
"$:/language/ControlPanel/Settings/NavigationHistory/Yes/Description": {
"title": "$:/language/ControlPanel/Settings/NavigationHistory/Yes/Description",
"text": "Update history"
},
"$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/Caption": {
"title": "$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/Caption",
"text": "Permalink/permaview Mode"
},
"$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/Hint": {
"title": "$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/Hint",
"text": "Choose how permalink/permaview is handled:"
},
"$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/CopyToClipboard/Description": {
"title": "$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/CopyToClipboard/Description",
"text": "Copy permalink/permaview URL to clipboard"
},
"$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/UpdateAddressBar/Description": {
"title": "$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/UpdateAddressBar/Description",
"text": "Update address bar with permalink/permaview URL"
},
"$:/language/ControlPanel/Settings/PerformanceInstrumentation/Caption": {
"title": "$:/language/ControlPanel/Settings/PerformanceInstrumentation/Caption",
"text": "Performance Instrumentation"
},
"$:/language/ControlPanel/Settings/PerformanceInstrumentation/Hint": {
"title": "$:/language/ControlPanel/Settings/PerformanceInstrumentation/Hint",
"text": "Displays performance statistics in the browser developer console. Requires reload to take effect"
},
"$:/language/ControlPanel/Settings/PerformanceInstrumentation/Description": {
"title": "$:/language/ControlPanel/Settings/PerformanceInstrumentation/Description",
"text": "Enable performance instrumentation"
},
"$:/language/ControlPanel/Settings/ToolbarButtonStyle/Caption": {
"title": "$:/language/ControlPanel/Settings/ToolbarButtonStyle/Caption",
"text": "Toolbar Button Style"
},
"$:/language/ControlPanel/Settings/ToolbarButtonStyle/Hint": {
"title": "$:/language/ControlPanel/Settings/ToolbarButtonStyle/Hint",
"text": "Choose the style for toolbar buttons:"
},
"$:/language/ControlPanel/Settings/ToolbarButtonStyle/Styles/Borderless": {
"title": "$:/language/ControlPanel/Settings/ToolbarButtonStyle/Styles/Borderless",
"text": "Borderless"
},
"$:/language/ControlPanel/Settings/ToolbarButtonStyle/Styles/Boxed": {
"title": "$:/language/ControlPanel/Settings/ToolbarButtonStyle/Styles/Boxed",
"text": "Boxed"
},
"$:/language/ControlPanel/Settings/ToolbarButtonStyle/Styles/Rounded": {
"title": "$:/language/ControlPanel/Settings/ToolbarButtonStyle/Styles/Rounded",
"text": "Rounded"
},
"$:/language/ControlPanel/Settings/ToolbarButtons/Caption": {
"title": "$:/language/ControlPanel/Settings/ToolbarButtons/Caption",
"text": "Toolbar Buttons"
},
"$:/language/ControlPanel/Settings/ToolbarButtons/Hint": {
"title": "$:/language/ControlPanel/Settings/ToolbarButtons/Hint",
"text": "Default toolbar button appearance:"
},
"$:/language/ControlPanel/Settings/ToolbarButtons/Icons/Description": {
"title": "$:/language/ControlPanel/Settings/ToolbarButtons/Icons/Description",
"text": "Include icon"
},
"$:/language/ControlPanel/Settings/ToolbarButtons/Text/Description": {
"title": "$:/language/ControlPanel/Settings/ToolbarButtons/Text/Description",
"text": "Include text"
},
"$:/language/ControlPanel/Settings/DefaultSidebarTab/Caption": {
"title": "$:/language/ControlPanel/Settings/DefaultSidebarTab/Caption",
"text": "Default Sidebar Tab"
},
"$:/language/ControlPanel/Settings/DefaultSidebarTab/Hint": {
"title": "$:/language/ControlPanel/Settings/DefaultSidebarTab/Hint",
"text": "Specify which sidebar tab is displayed by default"
},
"$:/language/ControlPanel/Settings/DefaultMoreSidebarTab/Caption": {
"title": "$:/language/ControlPanel/Settings/DefaultMoreSidebarTab/Caption",
"text": "Default More Sidebar Tab"
},
"$:/language/ControlPanel/Settings/DefaultMoreSidebarTab/Hint": {
"title": "$:/language/ControlPanel/Settings/DefaultMoreSidebarTab/Hint",
"text": "Specify which More sidebar tab is displayed by default"
},
"$:/language/ControlPanel/Settings/LinkToBehaviour/Caption": {
"title": "$:/language/ControlPanel/Settings/LinkToBehaviour/Caption",
"text": "Tiddler Opening Behaviour"
},
"$:/language/ControlPanel/Settings/LinkToBehaviour/InsideRiver/Hint": {
"title": "$:/language/ControlPanel/Settings/LinkToBehaviour/InsideRiver/Hint",
"text": "Navigation from //within// the story river"
},
"$:/language/ControlPanel/Settings/LinkToBehaviour/OutsideRiver/Hint": {
"title": "$:/language/ControlPanel/Settings/LinkToBehaviour/OutsideRiver/Hint",
"text": "Navigation from //outside// the story river"
},
"$:/language/ControlPanel/Settings/LinkToBehaviour/OpenAbove": {
"title": "$:/language/ControlPanel/Settings/LinkToBehaviour/OpenAbove",
"text": "Open above the current tiddler"
},
"$:/language/ControlPanel/Settings/LinkToBehaviour/OpenBelow": {
"title": "$:/language/ControlPanel/Settings/LinkToBehaviour/OpenBelow",
"text": "Open below the current tiddler"
},
"$:/language/ControlPanel/Settings/LinkToBehaviour/OpenAtTop": {
"title": "$:/language/ControlPanel/Settings/LinkToBehaviour/OpenAtTop",
"text": "Open at the top of the story river"
},
"$:/language/ControlPanel/Settings/LinkToBehaviour/OpenAtBottom": {
"title": "$:/language/ControlPanel/Settings/LinkToBehaviour/OpenAtBottom",
"text": "Open at the bottom of the story river"
},
"$:/language/ControlPanel/Settings/TitleLinks/Caption": {
"title": "$:/language/ControlPanel/Settings/TitleLinks/Caption",
"text": "Tiddler Titles"
},
"$:/language/ControlPanel/Settings/TitleLinks/Hint": {
"title": "$:/language/ControlPanel/Settings/TitleLinks/Hint",
"text": "Optionally display tiddler titles as links"
},
"$:/language/ControlPanel/Settings/TitleLinks/No/Description": {
"title": "$:/language/ControlPanel/Settings/TitleLinks/No/Description",
"text": "Do not display tiddler titles as links"
},
"$:/language/ControlPanel/Settings/TitleLinks/Yes/Description": {
"title": "$:/language/ControlPanel/Settings/TitleLinks/Yes/Description",
"text": "Display tiddler titles as links"
},
"$:/language/ControlPanel/Settings/MissingLinks/Caption": {
"title": "$:/language/ControlPanel/Settings/MissingLinks/Caption",
"text": "Wiki Links"
},
"$:/language/ControlPanel/Settings/MissingLinks/Hint": {
"title": "$:/language/ControlPanel/Settings/MissingLinks/Hint",
"text": "Choose whether to link to tiddlers that do not exist yet"
},
"$:/language/ControlPanel/Settings/MissingLinks/Description": {
"title": "$:/language/ControlPanel/Settings/MissingLinks/Description",
"text": "Enable links to missing tiddlers"
},
"$:/language/ControlPanel/StoryView/Caption": {
"title": "$:/language/ControlPanel/StoryView/Caption",
"text": "Story View"
},
"$:/language/ControlPanel/StoryView/Prompt": {
"title": "$:/language/ControlPanel/StoryView/Prompt",
"text": "Current view:"
},
"$:/language/ControlPanel/Stylesheets/Caption": {
"title": "$:/language/ControlPanel/Stylesheets/Caption",
"text": "Stylesheets"
},
"$:/language/ControlPanel/Stylesheets/Expand/Caption": {
"title": "$:/language/ControlPanel/Stylesheets/Expand/Caption",
"text": "Expand All"
},
"$:/language/ControlPanel/Stylesheets/Hint": {
"title": "$:/language/ControlPanel/Stylesheets/Hint",
"text": "This is the rendered CSS of the current stylesheet tiddlers tagged with <<tag \"$:/tags/Stylesheet\">>"
},
"$:/language/ControlPanel/Stylesheets/Restore/Caption": {
"title": "$:/language/ControlPanel/Stylesheets/Restore/Caption",
"text": "Restore"
},
"$:/language/ControlPanel/Theme/Caption": {
"title": "$:/language/ControlPanel/Theme/Caption",
"text": "Theme"
},
"$:/language/ControlPanel/Theme/Prompt": {
"title": "$:/language/ControlPanel/Theme/Prompt",
"text": "Current theme:"
},
"$:/language/ControlPanel/TiddlerFields/Caption": {
"title": "$:/language/ControlPanel/TiddlerFields/Caption",
"text": "Tiddler Fields"
},
"$:/language/ControlPanel/TiddlerFields/Hint": {
"title": "$:/language/ControlPanel/TiddlerFields/Hint",
"text": "This is the full set of TiddlerFields in use in this wiki (including system tiddlers but excluding shadow tiddlers)."
},
"$:/language/ControlPanel/Toolbars/Caption": {
"title": "$:/language/ControlPanel/Toolbars/Caption",
"text": "Toolbars"
},
"$:/language/ControlPanel/Toolbars/EditToolbar/Caption": {
"title": "$:/language/ControlPanel/Toolbars/EditToolbar/Caption",
"text": "Edit Toolbar"
},
"$:/language/ControlPanel/Toolbars/EditToolbar/Hint": {
"title": "$:/language/ControlPanel/Toolbars/EditToolbar/Hint",
"text": "Choose which buttons are displayed for tiddlers in edit mode. Drag and drop to change the ordering"
},
"$:/language/ControlPanel/Toolbars/Hint": {
"title": "$:/language/ControlPanel/Toolbars/Hint",
"text": "Select which toolbar buttons are displayed"
},
"$:/language/ControlPanel/Toolbars/PageControls/Caption": {
"title": "$:/language/ControlPanel/Toolbars/PageControls/Caption",
"text": "Page Toolbar"
},
"$:/language/ControlPanel/Toolbars/PageControls/Hint": {
"title": "$:/language/ControlPanel/Toolbars/PageControls/Hint",
"text": "Choose which buttons are displayed on the main page toolbar. Drag and drop to change the ordering"
},
"$:/language/ControlPanel/Toolbars/EditorToolbar/Caption": {
"title": "$:/language/ControlPanel/Toolbars/EditorToolbar/Caption",
"text": "Editor Toolbar"
},
"$:/language/ControlPanel/Toolbars/EditorToolbar/Hint": {
"title": "$:/language/ControlPanel/Toolbars/EditorToolbar/Hint",
"text": "Choose which buttons are displayed in the editor toolbar. Note that some buttons will only appear when editing tiddlers of a certain type. Drag and drop to change the ordering"
},
"$:/language/ControlPanel/Toolbars/ViewToolbar/Caption": {
"title": "$:/language/ControlPanel/Toolbars/ViewToolbar/Caption",
"text": "View Toolbar"
},
"$:/language/ControlPanel/Toolbars/ViewToolbar/Hint": {
"title": "$:/language/ControlPanel/Toolbars/ViewToolbar/Hint",
"text": "Choose which buttons are displayed for tiddlers in view mode. Drag and drop to change the ordering"
},
"$:/language/ControlPanel/Tools/Download/Full/Caption": {
"title": "$:/language/ControlPanel/Tools/Download/Full/Caption",
"text": "Download full wiki"
},
"$:/language/Date/DaySuffix/1": {
"title": "$:/language/Date/DaySuffix/1",
"text": "st"
},
"$:/language/Date/DaySuffix/2": {
"title": "$:/language/Date/DaySuffix/2",
"text": "nd"
},
"$:/language/Date/DaySuffix/3": {
"title": "$:/language/Date/DaySuffix/3",
"text": "rd"
},
"$:/language/Date/DaySuffix/4": {
"title": "$:/language/Date/DaySuffix/4",
"text": "th"
},
"$:/language/Date/DaySuffix/5": {
"title": "$:/language/Date/DaySuffix/5",
"text": "th"
},
"$:/language/Date/DaySuffix/6": {
"title": "$:/language/Date/DaySuffix/6",
"text": "th"
},
"$:/language/Date/DaySuffix/7": {
"title": "$:/language/Date/DaySuffix/7",
"text": "th"
},
"$:/language/Date/DaySuffix/8": {
"title": "$:/language/Date/DaySuffix/8",
"text": "th"
},
"$:/language/Date/DaySuffix/9": {
"title": "$:/language/Date/DaySuffix/9",
"text": "th"
},
"$:/language/Date/DaySuffix/10": {
"title": "$:/language/Date/DaySuffix/10",
"text": "th"
},
"$:/language/Date/DaySuffix/11": {
"title": "$:/language/Date/DaySuffix/11",
"text": "th"
},
"$:/language/Date/DaySuffix/12": {
"title": "$:/language/Date/DaySuffix/12",
"text": "th"
},
"$:/language/Date/DaySuffix/13": {
"title": "$:/language/Date/DaySuffix/13",
"text": "th"
},
"$:/language/Date/DaySuffix/14": {
"title": "$:/language/Date/DaySuffix/14",
"text": "th"
},
"$:/language/Date/DaySuffix/15": {
"title": "$:/language/Date/DaySuffix/15",
"text": "th"
},
"$:/language/Date/DaySuffix/16": {
"title": "$:/language/Date/DaySuffix/16",
"text": "th"
},
"$:/language/Date/DaySuffix/17": {
"title": "$:/language/Date/DaySuffix/17",
"text": "th"
},
"$:/language/Date/DaySuffix/18": {
"title": "$:/language/Date/DaySuffix/18",
"text": "th"
},
"$:/language/Date/DaySuffix/19": {
"title": "$:/language/Date/DaySuffix/19",
"text": "th"
},
"$:/language/Date/DaySuffix/20": {
"title": "$:/language/Date/DaySuffix/20",
"text": "th"
},
"$:/language/Date/DaySuffix/21": {
"title": "$:/language/Date/DaySuffix/21",
"text": "st"
},
"$:/language/Date/DaySuffix/22": {
"title": "$:/language/Date/DaySuffix/22",
"text": "nd"
},
"$:/language/Date/DaySuffix/23": {
"title": "$:/language/Date/DaySuffix/23",
"text": "rd"
},
"$:/language/Date/DaySuffix/24": {
"title": "$:/language/Date/DaySuffix/24",
"text": "th"
},
"$:/language/Date/DaySuffix/25": {
"title": "$:/language/Date/DaySuffix/25",
"text": "th"
},
"$:/language/Date/DaySuffix/26": {
"title": "$:/language/Date/DaySuffix/26",
"text": "th"
},
"$:/language/Date/DaySuffix/27": {
"title": "$:/language/Date/DaySuffix/27",
"text": "th"
},
"$:/language/Date/DaySuffix/28": {
"title": "$:/language/Date/DaySuffix/28",
"text": "th"
},
"$:/language/Date/DaySuffix/29": {
"title": "$:/language/Date/DaySuffix/29",
"text": "th"
},
"$:/language/Date/DaySuffix/30": {
"title": "$:/language/Date/DaySuffix/30",
"text": "th"
},
"$:/language/Date/DaySuffix/31": {
"title": "$:/language/Date/DaySuffix/31",
"text": "st"
},
"$:/language/Date/Long/Day/0": {
"title": "$:/language/Date/Long/Day/0",
"text": "Sunday"
},
"$:/language/Date/Long/Day/1": {
"title": "$:/language/Date/Long/Day/1",
"text": "Monday"
},
"$:/language/Date/Long/Day/2": {
"title": "$:/language/Date/Long/Day/2",
"text": "Tuesday"
},
"$:/language/Date/Long/Day/3": {
"title": "$:/language/Date/Long/Day/3",
"text": "Wednesday"
},
"$:/language/Date/Long/Day/4": {
"title": "$:/language/Date/Long/Day/4",
"text": "Thursday"
},
"$:/language/Date/Long/Day/5": {
"title": "$:/language/Date/Long/Day/5",
"text": "Friday"
},
"$:/language/Date/Long/Day/6": {
"title": "$:/language/Date/Long/Day/6",
"text": "Saturday"
},
"$:/language/Date/Long/Month/1": {
"title": "$:/language/Date/Long/Month/1",
"text": "January"
},
"$:/language/Date/Long/Month/2": {
"title": "$:/language/Date/Long/Month/2",
"text": "February"
},
"$:/language/Date/Long/Month/3": {
"title": "$:/language/Date/Long/Month/3",
"text": "March"
},
"$:/language/Date/Long/Month/4": {
"title": "$:/language/Date/Long/Month/4",
"text": "April"
},
"$:/language/Date/Long/Month/5": {
"title": "$:/language/Date/Long/Month/5",
"text": "May"
},
"$:/language/Date/Long/Month/6": {
"title": "$:/language/Date/Long/Month/6",
"text": "June"
},
"$:/language/Date/Long/Month/7": {
"title": "$:/language/Date/Long/Month/7",
"text": "July"
},
"$:/language/Date/Long/Month/8": {
"title": "$:/language/Date/Long/Month/8",
"text": "August"
},
"$:/language/Date/Long/Month/9": {
"title": "$:/language/Date/Long/Month/9",
"text": "September"
},
"$:/language/Date/Long/Month/10": {
"title": "$:/language/Date/Long/Month/10",
"text": "October"
},
"$:/language/Date/Long/Month/11": {
"title": "$:/language/Date/Long/Month/11",
"text": "November"
},
"$:/language/Date/Long/Month/12": {
"title": "$:/language/Date/Long/Month/12",
"text": "December"
},
"$:/language/Date/Period/am": {
"title": "$:/language/Date/Period/am",
"text": "am"
},
"$:/language/Date/Period/pm": {
"title": "$:/language/Date/Period/pm",
"text": "pm"
},
"$:/language/Date/Short/Day/0": {
"title": "$:/language/Date/Short/Day/0",
"text": "Sun"
},
"$:/language/Date/Short/Day/1": {
"title": "$:/language/Date/Short/Day/1",
"text": "Mon"
},
"$:/language/Date/Short/Day/2": {
"title": "$:/language/Date/Short/Day/2",
"text": "Tue"
},
"$:/language/Date/Short/Day/3": {
"title": "$:/language/Date/Short/Day/3",
"text": "Wed"
},
"$:/language/Date/Short/Day/4": {
"title": "$:/language/Date/Short/Day/4",
"text": "Thu"
},
"$:/language/Date/Short/Day/5": {
"title": "$:/language/Date/Short/Day/5",
"text": "Fri"
},
"$:/language/Date/Short/Day/6": {
"title": "$:/language/Date/Short/Day/6",
"text": "Sat"
},
"$:/language/Date/Short/Month/1": {
"title": "$:/language/Date/Short/Month/1",
"text": "Jan"
},
"$:/language/Date/Short/Month/2": {
"title": "$:/language/Date/Short/Month/2",
"text": "Feb"
},
"$:/language/Date/Short/Month/3": {
"title": "$:/language/Date/Short/Month/3",
"text": "Mar"
},
"$:/language/Date/Short/Month/4": {
"title": "$:/language/Date/Short/Month/4",
"text": "Apr"
},
"$:/language/Date/Short/Month/5": {
"title": "$:/language/Date/Short/Month/5",
"text": "May"
},
"$:/language/Date/Short/Month/6": {
"title": "$:/language/Date/Short/Month/6",
"text": "Jun"
},
"$:/language/Date/Short/Month/7": {
"title": "$:/language/Date/Short/Month/7",
"text": "Jul"
},
"$:/language/Date/Short/Month/8": {
"title": "$:/language/Date/Short/Month/8",
"text": "Aug"
},
"$:/language/Date/Short/Month/9": {
"title": "$:/language/Date/Short/Month/9",
"text": "Sep"
},
"$:/language/Date/Short/Month/10": {
"title": "$:/language/Date/Short/Month/10",
"text": "Oct"
},
"$:/language/Date/Short/Month/11": {
"title": "$:/language/Date/Short/Month/11",
"text": "Nov"
},
"$:/language/Date/Short/Month/12": {
"title": "$:/language/Date/Short/Month/12",
"text": "Dec"
},
"$:/language/RelativeDate/Future/Days": {
"title": "$:/language/RelativeDate/Future/Days",
"text": "<<period>> days from now"
},
"$:/language/RelativeDate/Future/Hours": {
"title": "$:/language/RelativeDate/Future/Hours",
"text": "<<period>> hours from now"
},
"$:/language/RelativeDate/Future/Minutes": {
"title": "$:/language/RelativeDate/Future/Minutes",
"text": "<<period>> minutes from now"
},
"$:/language/RelativeDate/Future/Months": {
"title": "$:/language/RelativeDate/Future/Months",
"text": "<<period>> months from now"
},
"$:/language/RelativeDate/Future/Second": {
"title": "$:/language/RelativeDate/Future/Second",
"text": "1 second from now"
},
"$:/language/RelativeDate/Future/Seconds": {
"title": "$:/language/RelativeDate/Future/Seconds",
"text": "<<period>> seconds from now"
},
"$:/language/RelativeDate/Future/Years": {
"title": "$:/language/RelativeDate/Future/Years",
"text": "<<period>> years from now"
},
"$:/language/RelativeDate/Past/Days": {
"title": "$:/language/RelativeDate/Past/Days",
"text": "<<period>> days ago"
},
"$:/language/RelativeDate/Past/Hours": {
"title": "$:/language/RelativeDate/Past/Hours",
"text": "<<period>> hours ago"
},
"$:/language/RelativeDate/Past/Minutes": {
"title": "$:/language/RelativeDate/Past/Minutes",
"text": "<<period>> minutes ago"
},
"$:/language/RelativeDate/Past/Months": {
"title": "$:/language/RelativeDate/Past/Months",
"text": "<<period>> months ago"
},
"$:/language/RelativeDate/Past/Second": {
"title": "$:/language/RelativeDate/Past/Second",
"text": "1 second ago"
},
"$:/language/RelativeDate/Past/Seconds": {
"title": "$:/language/RelativeDate/Past/Seconds",
"text": "<<period>> seconds ago"
},
"$:/language/RelativeDate/Past/Years": {
"title": "$:/language/RelativeDate/Past/Years",
"text": "<<period>> years ago"
},
"$:/language/Docs/ModuleTypes/allfilteroperator": {
"title": "$:/language/Docs/ModuleTypes/allfilteroperator",
"text": "A sub-operator for the ''all'' filter operator."
},
"$:/language/Docs/ModuleTypes/animation": {
"title": "$:/language/Docs/ModuleTypes/animation",
"text": "Animations that may be used with the RevealWidget."
},
"$:/language/Docs/ModuleTypes/authenticator": {
"title": "$:/language/Docs/ModuleTypes/authenticator",
"text": "Defines how requests are authenticated by the built-in HTTP server."
},
"$:/language/Docs/ModuleTypes/bitmapeditoroperation": {
"title": "$:/language/Docs/ModuleTypes/bitmapeditoroperation",
"text": "A bitmap editor toolbar operation."
},
"$:/language/Docs/ModuleTypes/command": {
"title": "$:/language/Docs/ModuleTypes/command",
"text": "Commands that can be executed under Node.js."
},
"$:/language/Docs/ModuleTypes/config": {
"title": "$:/language/Docs/ModuleTypes/config",
"text": "Data to be inserted into `$tw.config`."
},
"$:/language/Docs/ModuleTypes/filteroperator": {
"title": "$:/language/Docs/ModuleTypes/filteroperator",
"text": "Individual filter operator methods."
},
"$:/language/Docs/ModuleTypes/global": {
"title": "$:/language/Docs/ModuleTypes/global",
"text": "Global data to be inserted into `$tw`."
},
"$:/language/Docs/ModuleTypes/info": {
"title": "$:/language/Docs/ModuleTypes/info",
"text": "Publishes system information via the [[$:/temp/info-plugin]] pseudo-plugin."
},
"$:/language/Docs/ModuleTypes/isfilteroperator": {
"title": "$:/language/Docs/ModuleTypes/isfilteroperator",
"text": "Operands for the ''is'' filter operator."
},
"$:/language/Docs/ModuleTypes/library": {
"title": "$:/language/Docs/ModuleTypes/library",
"text": "Generic module type for general purpose JavaScript modules."
},
"$:/language/Docs/ModuleTypes/macro": {
"title": "$:/language/Docs/ModuleTypes/macro",
"text": "JavaScript macro definitions."
},
"$:/language/Docs/ModuleTypes/parser": {
"title": "$:/language/Docs/ModuleTypes/parser",
"text": "Parsers for different content types."
},
"$:/language/Docs/ModuleTypes/route": {
"title": "$:/language/Docs/ModuleTypes/route",
"text": "Defines how individual URL patterns are handled by the built-in HTTP server."
},
"$:/language/Docs/ModuleTypes/saver": {
"title": "$:/language/Docs/ModuleTypes/saver",
"text": "Savers handle different methods for saving files from the browser."
},
"$:/language/Docs/ModuleTypes/startup": {
"title": "$:/language/Docs/ModuleTypes/startup",
"text": "Startup functions."
},
"$:/language/Docs/ModuleTypes/storyview": {
"title": "$:/language/Docs/ModuleTypes/storyview",
"text": "Story views customise the animation and behaviour of list widgets."
},
"$:/language/Docs/ModuleTypes/texteditoroperation": {
"title": "$:/language/Docs/ModuleTypes/texteditoroperation",
"text": "A text editor toolbar operation."
},
"$:/language/Docs/ModuleTypes/tiddlerdeserializer": {
"title": "$:/language/Docs/ModuleTypes/tiddlerdeserializer",
"text": "Converts different content types into tiddlers."
},
"$:/language/Docs/ModuleTypes/tiddlerfield": {
"title": "$:/language/Docs/ModuleTypes/tiddlerfield",
"text": "Defines the behaviour of an individual tiddler field."
},
"$:/language/Docs/ModuleTypes/tiddlermethod": {
"title": "$:/language/Docs/ModuleTypes/tiddlermethod",
"text": "Adds methods to the `$tw.Tiddler` prototype."
},
"$:/language/Docs/ModuleTypes/upgrader": {
"title": "$:/language/Docs/ModuleTypes/upgrader",
"text": "Applies upgrade processing to tiddlers during an upgrade/import."
},
"$:/language/Docs/ModuleTypes/utils": {
"title": "$:/language/Docs/ModuleTypes/utils",
"text": "Adds methods to `$tw.utils`."
},
"$:/language/Docs/ModuleTypes/utils-node": {
"title": "$:/language/Docs/ModuleTypes/utils-node",
"text": "Adds Node.js-specific methods to `$tw.utils`."
},
"$:/language/Docs/ModuleTypes/widget": {
"title": "$:/language/Docs/ModuleTypes/widget",
"text": "Widgets encapsulate DOM rendering and refreshing."
},
"$:/language/Docs/ModuleTypes/wikimethod": {
"title": "$:/language/Docs/ModuleTypes/wikimethod",
"text": "Adds methods to `$tw.Wiki`."
},
"$:/language/Docs/ModuleTypes/wikirule": {
"title": "$:/language/Docs/ModuleTypes/wikirule",
"text": "Individual parser rules for the main WikiText parser."
},
"$:/language/Docs/PaletteColours/alert-background": {
"title": "$:/language/Docs/PaletteColours/alert-background",
"text": "Alert background"
},
"$:/language/Docs/PaletteColours/alert-border": {
"title": "$:/language/Docs/PaletteColours/alert-border",
"text": "Alert border"
},
"$:/language/Docs/PaletteColours/alert-highlight": {
"title": "$:/language/Docs/PaletteColours/alert-highlight",
"text": "Alert highlight"
},
"$:/language/Docs/PaletteColours/alert-muted-foreground": {
"title": "$:/language/Docs/PaletteColours/alert-muted-foreground",
"text": "Alert muted foreground"
},
"$:/language/Docs/PaletteColours/background": {
"title": "$:/language/Docs/PaletteColours/background",
"text": "General background"
},
"$:/language/Docs/PaletteColours/blockquote-bar": {
"title": "$:/language/Docs/PaletteColours/blockquote-bar",
"text": "Blockquote bar"
},
"$:/language/Docs/PaletteColours/button-background": {
"title": "$:/language/Docs/PaletteColours/button-background",
"text": "Default button background"
},
"$:/language/Docs/PaletteColours/button-border": {
"title": "$:/language/Docs/PaletteColours/button-border",
"text": "Default button border"
},
"$:/language/Docs/PaletteColours/button-foreground": {
"title": "$:/language/Docs/PaletteColours/button-foreground",
"text": "Default button foreground"
},
"$:/language/Docs/PaletteColours/dirty-indicator": {
"title": "$:/language/Docs/PaletteColours/dirty-indicator",
"text": "Unsaved changes indicator"
},
"$:/language/Docs/PaletteColours/code-background": {
"title": "$:/language/Docs/PaletteColours/code-background",
"text": "Code background"
},
"$:/language/Docs/PaletteColours/code-border": {
"title": "$:/language/Docs/PaletteColours/code-border",
"text": "Code border"
},
"$:/language/Docs/PaletteColours/code-foreground": {
"title": "$:/language/Docs/PaletteColours/code-foreground",
"text": "Code foreground"
},
"$:/language/Docs/PaletteColours/download-background": {
"title": "$:/language/Docs/PaletteColours/download-background",
"text": "Download button background"
},
"$:/language/Docs/PaletteColours/download-foreground": {
"title": "$:/language/Docs/PaletteColours/download-foreground",
"text": "Download button foreground"
},
"$:/language/Docs/PaletteColours/dragger-background": {
"title": "$:/language/Docs/PaletteColours/dragger-background",
"text": "Dragger background"
},
"$:/language/Docs/PaletteColours/dragger-foreground": {
"title": "$:/language/Docs/PaletteColours/dragger-foreground",
"text": "Dragger foreground"
},
"$:/language/Docs/PaletteColours/dropdown-background": {
"title": "$:/language/Docs/PaletteColours/dropdown-background",
"text": "Dropdown background"
},
"$:/language/Docs/PaletteColours/dropdown-border": {
"title": "$:/language/Docs/PaletteColours/dropdown-border",
"text": "Dropdown border"
},
"$:/language/Docs/PaletteColours/dropdown-tab-background-selected": {
"title": "$:/language/Docs/PaletteColours/dropdown-tab-background-selected",
"text": "Dropdown tab background for selected tabs"
},
"$:/language/Docs/PaletteColours/dropdown-tab-background": {
"title": "$:/language/Docs/PaletteColours/dropdown-tab-background",
"text": "Dropdown tab background"
},
"$:/language/Docs/PaletteColours/dropzone-background": {
"title": "$:/language/Docs/PaletteColours/dropzone-background",
"text": "Dropzone background"
},
"$:/language/Docs/PaletteColours/external-link-background-hover": {
"title": "$:/language/Docs/PaletteColours/external-link-background-hover",
"text": "External link background hover"
},
"$:/language/Docs/PaletteColours/external-link-background-visited": {
"title": "$:/language/Docs/PaletteColours/external-link-background-visited",
"text": "External link background visited"
},
"$:/language/Docs/PaletteColours/external-link-background": {
"title": "$:/language/Docs/PaletteColours/external-link-background",
"text": "External link background"
},
"$:/language/Docs/PaletteColours/external-link-foreground-hover": {
"title": "$:/language/Docs/PaletteColours/external-link-foreground-hover",
"text": "External link foreground hover"
},
"$:/language/Docs/PaletteColours/external-link-foreground-visited": {
"title": "$:/language/Docs/PaletteColours/external-link-foreground-visited",
"text": "External link foreground visited"
},
"$:/language/Docs/PaletteColours/external-link-foreground": {
"title": "$:/language/Docs/PaletteColours/external-link-foreground",
"text": "External link foreground"
},
"$:/language/Docs/PaletteColours/foreground": {
"title": "$:/language/Docs/PaletteColours/foreground",
"text": "General foreground"
},
"$:/language/Docs/PaletteColours/message-background": {
"title": "$:/language/Docs/PaletteColours/message-background",
"text": "Message box background"
},
"$:/language/Docs/PaletteColours/message-border": {
"title": "$:/language/Docs/PaletteColours/message-border",
"text": "Message box border"
},
"$:/language/Docs/PaletteColours/message-foreground": {
"title": "$:/language/Docs/PaletteColours/message-foreground",
"text": "Message box foreground"
},
"$:/language/Docs/PaletteColours/modal-backdrop": {
"title": "$:/language/Docs/PaletteColours/modal-backdrop",
"text": "Modal backdrop"
},
"$:/language/Docs/PaletteColours/modal-background": {
"title": "$:/language/Docs/PaletteColours/modal-background",
"text": "Modal background"
},
"$:/language/Docs/PaletteColours/modal-border": {
"title": "$:/language/Docs/PaletteColours/modal-border",
"text": "Modal border"
},
"$:/language/Docs/PaletteColours/modal-footer-background": {
"title": "$:/language/Docs/PaletteColours/modal-footer-background",
"text": "Modal footer background"
},
"$:/language/Docs/PaletteColours/modal-footer-border": {
"title": "$:/language/Docs/PaletteColours/modal-footer-border",
"text": "Modal footer border"
},
"$:/language/Docs/PaletteColours/modal-header-border": {
"title": "$:/language/Docs/PaletteColours/modal-header-border",
"text": "Modal header border"
},
"$:/language/Docs/PaletteColours/muted-foreground": {
"title": "$:/language/Docs/PaletteColours/muted-foreground",
"text": "General muted foreground"
},
"$:/language/Docs/PaletteColours/notification-background": {
"title": "$:/language/Docs/PaletteColours/notification-background",
"text": "Notification background"
},
"$:/language/Docs/PaletteColours/notification-border": {
"title": "$:/language/Docs/PaletteColours/notification-border",
"text": "Notification border"
},
"$:/language/Docs/PaletteColours/page-background": {
"title": "$:/language/Docs/PaletteColours/page-background",
"text": "Page background"
},
"$:/language/Docs/PaletteColours/pre-background": {
"title": "$:/language/Docs/PaletteColours/pre-background",
"text": "Preformatted code background"
},
"$:/language/Docs/PaletteColours/pre-border": {
"title": "$:/language/Docs/PaletteColours/pre-border",
"text": "Preformatted code border"
},
"$:/language/Docs/PaletteColours/primary": {
"title": "$:/language/Docs/PaletteColours/primary",
"text": "General primary"
},
"$:/language/Docs/PaletteColours/select-tag-background": {
"title": "$:/language/Docs/PaletteColours/select-tag-background",
"text": "`<select>` element background"
},
"$:/language/Docs/PaletteColours/select-tag-foreground": {
"title": "$:/language/Docs/PaletteColours/select-tag-foreground",
"text": "`<select>` element text"
},
"$:/language/Docs/PaletteColours/sidebar-button-foreground": {
"title": "$:/language/Docs/PaletteColours/sidebar-button-foreground",
"text": "Sidebar button foreground"
},
"$:/language/Docs/PaletteColours/sidebar-controls-foreground-hover": {
"title": "$:/language/Docs/PaletteColours/sidebar-controls-foreground-hover",
"text": "Sidebar controls foreground hover"
},
"$:/language/Docs/PaletteColours/sidebar-controls-foreground": {
"title": "$:/language/Docs/PaletteColours/sidebar-controls-foreground",
"text": "Sidebar controls foreground"
},
"$:/language/Docs/PaletteColours/sidebar-foreground-shadow": {
"title": "$:/language/Docs/PaletteColours/sidebar-foreground-shadow",
"text": "Sidebar foreground shadow"
},
"$:/language/Docs/PaletteColours/sidebar-foreground": {
"title": "$:/language/Docs/PaletteColours/sidebar-foreground",
"text": "Sidebar foreground"
},
"$:/language/Docs/PaletteColours/sidebar-muted-foreground-hover": {
"title": "$:/language/Docs/PaletteColours/sidebar-muted-foreground-hover",
"text": "Sidebar muted foreground hover"
},
"$:/language/Docs/PaletteColours/sidebar-muted-foreground": {
"title": "$:/language/Docs/PaletteColours/sidebar-muted-foreground",
"text": "Sidebar muted foreground"
},
"$:/language/Docs/PaletteColours/sidebar-tab-background-selected": {
"title": "$:/language/Docs/PaletteColours/sidebar-tab-background-selected",
"text": "Sidebar tab background for selected tabs"
},
"$:/language/Docs/PaletteColours/sidebar-tab-background": {
"title": "$:/language/Docs/PaletteColours/sidebar-tab-background",
"text": "Sidebar tab background"
},
"$:/language/Docs/PaletteColours/sidebar-tab-border-selected": {
"title": "$:/language/Docs/PaletteColours/sidebar-tab-border-selected",
"text": "Sidebar tab border for selected tabs"
},
"$:/language/Docs/PaletteColours/sidebar-tab-border": {
"title": "$:/language/Docs/PaletteColours/sidebar-tab-border",
"text": "Sidebar tab border"
},
"$:/language/Docs/PaletteColours/sidebar-tab-divider": {
"title": "$:/language/Docs/PaletteColours/sidebar-tab-divider",
"text": "Sidebar tab divider"
},
"$:/language/Docs/PaletteColours/sidebar-tab-foreground-selected": {
"title": "$:/language/Docs/PaletteColours/sidebar-tab-foreground-selected",
"text": "Sidebar tab foreground for selected tabs"
},
"$:/language/Docs/PaletteColours/sidebar-tab-foreground": {
"title": "$:/language/Docs/PaletteColours/sidebar-tab-foreground",
"text": "Sidebar tab foreground"
},
"$:/language/Docs/PaletteColours/sidebar-tiddler-link-foreground-hover": {
"title": "$:/language/Docs/PaletteColours/sidebar-tiddler-link-foreground-hover",
"text": "Sidebar tiddler link foreground hover"
},
"$:/language/Docs/PaletteColours/sidebar-tiddler-link-foreground": {
"title": "$:/language/Docs/PaletteColours/sidebar-tiddler-link-foreground",
"text": "Sidebar tiddler link foreground"
},
"$:/language/Docs/PaletteColours/site-title-foreground": {
"title": "$:/language/Docs/PaletteColours/site-title-foreground",
"text": "Site title foreground"
},
"$:/language/Docs/PaletteColours/static-alert-foreground": {
"title": "$:/language/Docs/PaletteColours/static-alert-foreground",
"text": "Static alert foreground"
},
"$:/language/Docs/PaletteColours/tab-background-selected": {
"title": "$:/language/Docs/PaletteColours/tab-background-selected",
"text": "Tab background for selected tabs"
},
"$:/language/Docs/PaletteColours/tab-background": {
"title": "$:/language/Docs/PaletteColours/tab-background",
"text": "Tab background"
},
"$:/language/Docs/PaletteColours/tab-border-selected": {
"title": "$:/language/Docs/PaletteColours/tab-border-selected",
"text": "Tab border for selected tabs"
},
"$:/language/Docs/PaletteColours/tab-border": {
"title": "$:/language/Docs/PaletteColours/tab-border",
"text": "Tab border"
},
"$:/language/Docs/PaletteColours/tab-divider": {
"title": "$:/language/Docs/PaletteColours/tab-divider",
"text": "Tab divider"
},
"$:/language/Docs/PaletteColours/tab-foreground-selected": {
"title": "$:/language/Docs/PaletteColours/tab-foreground-selected",
"text": "Tab foreground for selected tabs"
},
"$:/language/Docs/PaletteColours/tab-foreground": {
"title": "$:/language/Docs/PaletteColours/tab-foreground",
"text": "Tab foreground"
},
"$:/language/Docs/PaletteColours/table-border": {
"title": "$:/language/Docs/PaletteColours/table-border",
"text": "Table border"
},
"$:/language/Docs/PaletteColours/table-footer-background": {
"title": "$:/language/Docs/PaletteColours/table-footer-background",
"text": "Table footer background"
},
"$:/language/Docs/PaletteColours/table-header-background": {
"title": "$:/language/Docs/PaletteColours/table-header-background",
"text": "Table header background"
},
"$:/language/Docs/PaletteColours/tag-background": {
"title": "$:/language/Docs/PaletteColours/tag-background",
"text": "Tag background"
},
"$:/language/Docs/PaletteColours/tag-foreground": {
"title": "$:/language/Docs/PaletteColours/tag-foreground",
"text": "Tag foreground"
},
"$:/language/Docs/PaletteColours/tiddler-background": {
"title": "$:/language/Docs/PaletteColours/tiddler-background",
"text": "Tiddler background"
},
"$:/language/Docs/PaletteColours/tiddler-border": {
"title": "$:/language/Docs/PaletteColours/tiddler-border",
"text": "Tiddler border"
},
"$:/language/Docs/PaletteColours/tiddler-controls-foreground-hover": {
"title": "$:/language/Docs/PaletteColours/tiddler-controls-foreground-hover",
"text": "Tiddler controls foreground hover"
},
"$:/language/Docs/PaletteColours/tiddler-controls-foreground-selected": {
"title": "$:/language/Docs/PaletteColours/tiddler-controls-foreground-selected",
"text": "Tiddler controls foreground for selected controls"
},
"$:/language/Docs/PaletteColours/tiddler-controls-foreground": {
"title": "$:/language/Docs/PaletteColours/tiddler-controls-foreground",
"text": "Tiddler controls foreground"
},
"$:/language/Docs/PaletteColours/tiddler-editor-background": {
"title": "$:/language/Docs/PaletteColours/tiddler-editor-background",
"text": "Tiddler editor background"
},
"$:/language/Docs/PaletteColours/tiddler-editor-border-image": {
"title": "$:/language/Docs/PaletteColours/tiddler-editor-border-image",
"text": "Tiddler editor border image"
},
"$:/language/Docs/PaletteColours/tiddler-editor-border": {
"title": "$:/language/Docs/PaletteColours/tiddler-editor-border",
"text": "Tiddler editor border"
},
"$:/language/Docs/PaletteColours/tiddler-editor-fields-even": {
"title": "$:/language/Docs/PaletteColours/tiddler-editor-fields-even",
"text": "Tiddler editor background for even fields"
},
"$:/language/Docs/PaletteColours/tiddler-editor-fields-odd": {
"title": "$:/language/Docs/PaletteColours/tiddler-editor-fields-odd",
"text": "Tiddler editor background for odd fields"
},
"$:/language/Docs/PaletteColours/tiddler-info-background": {
"title": "$:/language/Docs/PaletteColours/tiddler-info-background",
"text": "Tiddler info panel background"
},
"$:/language/Docs/PaletteColours/tiddler-info-border": {
"title": "$:/language/Docs/PaletteColours/tiddler-info-border",
"text": "Tiddler info panel border"
},
"$:/language/Docs/PaletteColours/tiddler-info-tab-background": {
"title": "$:/language/Docs/PaletteColours/tiddler-info-tab-background",
"text": "Tiddler info panel tab background"
},
"$:/language/Docs/PaletteColours/tiddler-link-background": {
"title": "$:/language/Docs/PaletteColours/tiddler-link-background",
"text": "Tiddler link background"
},
"$:/language/Docs/PaletteColours/tiddler-link-foreground": {
"title": "$:/language/Docs/PaletteColours/tiddler-link-foreground",
"text": "Tiddler link foreground"
},
"$:/language/Docs/PaletteColours/tiddler-subtitle-foreground": {
"title": "$:/language/Docs/PaletteColours/tiddler-subtitle-foreground",
"text": "Tiddler subtitle foreground"
},
"$:/language/Docs/PaletteColours/tiddler-title-foreground": {
"title": "$:/language/Docs/PaletteColours/tiddler-title-foreground",
"text": "Tiddler title foreground"
},
"$:/language/Docs/PaletteColours/toolbar-new-button": {
"title": "$:/language/Docs/PaletteColours/toolbar-new-button",
"text": "Toolbar 'new tiddler' button foreground"
},
"$:/language/Docs/PaletteColours/toolbar-options-button": {
"title": "$:/language/Docs/PaletteColours/toolbar-options-button",
"text": "Toolbar 'options' button foreground"
},
"$:/language/Docs/PaletteColours/toolbar-save-button": {
"title": "$:/language/Docs/PaletteColours/toolbar-save-button",
"text": "Toolbar 'save' button foreground"
},
"$:/language/Docs/PaletteColours/toolbar-info-button": {
"title": "$:/language/Docs/PaletteColours/toolbar-info-button",
"text": "Toolbar 'info' button foreground"
},
"$:/language/Docs/PaletteColours/toolbar-edit-button": {
"title": "$:/language/Docs/PaletteColours/toolbar-edit-button",
"text": "Toolbar 'edit' button foreground"
},
"$:/language/Docs/PaletteColours/toolbar-close-button": {
"title": "$:/language/Docs/PaletteColours/toolbar-close-button",
"text": "Toolbar 'close' button foreground"
},
"$:/language/Docs/PaletteColours/toolbar-delete-button": {
"title": "$:/language/Docs/PaletteColours/toolbar-delete-button",
"text": "Toolbar 'delete' button foreground"
},
"$:/language/Docs/PaletteColours/toolbar-cancel-button": {
"title": "$:/language/Docs/PaletteColours/toolbar-cancel-button",
"text": "Toolbar 'cancel' button foreground"
},
"$:/language/Docs/PaletteColours/toolbar-done-button": {
"title": "$:/language/Docs/PaletteColours/toolbar-done-button",
"text": "Toolbar 'done' button foreground"
},
"$:/language/Docs/PaletteColours/untagged-background": {
"title": "$:/language/Docs/PaletteColours/untagged-background",
"text": "Untagged pill background"
},
"$:/language/Docs/PaletteColours/very-muted-foreground": {
"title": "$:/language/Docs/PaletteColours/very-muted-foreground",
"text": "Very muted foreground"
},
"$:/language/EditTemplate/Body/External/Hint": {
"title": "$:/language/EditTemplate/Body/External/Hint",
"text": "This tiddler shows content stored outside of the main TiddlyWiki file. You can edit the tags and fields but cannot directly edit the content itself"
},
"$:/language/EditTemplate/Body/Placeholder": {
"title": "$:/language/EditTemplate/Body/Placeholder",
"text": "Type the text for this tiddler"
},
"$:/language/EditTemplate/Body/Preview/Type/Output": {
"title": "$:/language/EditTemplate/Body/Preview/Type/Output",
"text": "output"
},
"$:/language/EditTemplate/Field/Remove/Caption": {
"title": "$:/language/EditTemplate/Field/Remove/Caption",
"text": "remove field"
},
"$:/language/EditTemplate/Field/Remove/Hint": {
"title": "$:/language/EditTemplate/Field/Remove/Hint",
"text": "Remove field"
},
"$:/language/EditTemplate/Field/Dropdown/Caption": {
"title": "$:/language/EditTemplate/Field/Dropdown/Caption",
"text": "field list"
},
"$:/language/EditTemplate/Field/Dropdown/Hint": {
"title": "$:/language/EditTemplate/Field/Dropdown/Hint",
"text": "Show field list"
},
"$:/language/EditTemplate/Fields/Add/Button": {
"title": "$:/language/EditTemplate/Fields/Add/Button",
"text": "add"
},
"$:/language/EditTemplate/Fields/Add/Name/Placeholder": {
"title": "$:/language/EditTemplate/Fields/Add/Name/Placeholder",
"text": "field name"
},
"$:/language/EditTemplate/Fields/Add/Prompt": {
"title": "$:/language/EditTemplate/Fields/Add/Prompt",
"text": "Add a new field:"
},
"$:/language/EditTemplate/Fields/Add/Value/Placeholder": {
"title": "$:/language/EditTemplate/Fields/Add/Value/Placeholder",
"text": "field value"
},
"$:/language/EditTemplate/Fields/Add/Dropdown/System": {
"title": "$:/language/EditTemplate/Fields/Add/Dropdown/System",
"text": "System fields"
},
"$:/language/EditTemplate/Fields/Add/Dropdown/User": {
"title": "$:/language/EditTemplate/Fields/Add/Dropdown/User",
"text": "User fields"
},
"$:/language/EditTemplate/Shadow/Warning": {
"title": "$:/language/EditTemplate/Shadow/Warning",
"text": "This is a shadow tiddler. Any changes you make will override the default version from the plugin <<pluginLink>>"
},
"$:/language/EditTemplate/Shadow/OverriddenWarning": {
"title": "$:/language/EditTemplate/Shadow/OverriddenWarning",
"text": "This is a modified shadow tiddler. You can revert to the default version in the plugin <<pluginLink>> by deleting this tiddler"
},
"$:/language/EditTemplate/Tags/Add/Button": {
"title": "$:/language/EditTemplate/Tags/Add/Button",
"text": "add"
},
"$:/language/EditTemplate/Tags/Add/Placeholder": {
"title": "$:/language/EditTemplate/Tags/Add/Placeholder",
"text": "tag name"
},
"$:/language/EditTemplate/Tags/Dropdown/Caption": {
"title": "$:/language/EditTemplate/Tags/Dropdown/Caption",
"text": "tag list"
},
"$:/language/EditTemplate/Tags/Dropdown/Hint": {
"title": "$:/language/EditTemplate/Tags/Dropdown/Hint",
"text": "Show tag list"
},
"$:/language/EditTemplate/Title/BadCharacterWarning": {
"title": "$:/language/EditTemplate/Title/BadCharacterWarning",
"text": "Warning: avoid using any of the characters <<bad-chars>> in tiddler titles"
},
"$:/language/EditTemplate/Title/Exists/Prompt": {
"title": "$:/language/EditTemplate/Title/Exists/Prompt",
"text": "Target tiddler already exists"
},
"$:/language/EditTemplate/Title/Relink/Prompt": {
"title": "$:/language/EditTemplate/Title/Relink/Prompt",
"text": "Update ''<$text text=<<fromTitle>>/>'' to ''<$text text=<<toTitle>>/>'' in the //tags// and //list// fields of other tiddlers"
},
"$:/language/EditTemplate/Title/References/Prompt": {
"title": "$:/language/EditTemplate/Title/References/Prompt",
"text": "The following references to this tiddler will not be automatically updated:"
},
"$:/language/EditTemplate/Type/Dropdown/Caption": {
"title": "$:/language/EditTemplate/Type/Dropdown/Caption",
"text": "content type list"
},
"$:/language/EditTemplate/Type/Dropdown/Hint": {
"title": "$:/language/EditTemplate/Type/Dropdown/Hint",
"text": "Show content type list"
},
"$:/language/EditTemplate/Type/Delete/Caption": {
"title": "$:/language/EditTemplate/Type/Delete/Caption",
"text": "delete content type"
},
"$:/language/EditTemplate/Type/Delete/Hint": {
"title": "$:/language/EditTemplate/Type/Delete/Hint",
"text": "Delete content type"
},
"$:/language/EditTemplate/Type/Placeholder": {
"title": "$:/language/EditTemplate/Type/Placeholder",
"text": "content type"
},
"$:/language/EditTemplate/Type/Prompt": {
"title": "$:/language/EditTemplate/Type/Prompt",
"text": "Type:"
},
"$:/language/Exporters/StaticRiver": {
"title": "$:/language/Exporters/StaticRiver",
"text": "Static HTML"
},
"$:/language/Exporters/JsonFile": {
"title": "$:/language/Exporters/JsonFile",
"text": "JSON file"
},
"$:/language/Exporters/CsvFile": {
"title": "$:/language/Exporters/CsvFile",
"text": "CSV file"
},
"$:/language/Exporters/TidFile": {
"title": "$:/language/Exporters/TidFile",
"text": "\".tid\" file"
},
"$:/language/Docs/Fields/_canonical_uri": {
"title": "$:/language/Docs/Fields/_canonical_uri",
"text": "The full URI of an external image tiddler"
},
"$:/language/Docs/Fields/bag": {
"title": "$:/language/Docs/Fields/bag",
"text": "The name of the bag from which a tiddler came"
},
"$:/language/Docs/Fields/caption": {
"title": "$:/language/Docs/Fields/caption",
"text": "The text to be displayed on a tab or button"
},
"$:/language/Docs/Fields/color": {
"title": "$:/language/Docs/Fields/color",
"text": "The CSS color value associated with a tiddler"
},
"$:/language/Docs/Fields/component": {
"title": "$:/language/Docs/Fields/component",
"text": "The name of the component responsible for an [[alert tiddler|AlertMechanism]]"
},
"$:/language/Docs/Fields/current-tiddler": {
"title": "$:/language/Docs/Fields/current-tiddler",
"text": "Used to cache the top tiddler in a [[history list|HistoryMechanism]]"
},
"$:/language/Docs/Fields/created": {
"title": "$:/language/Docs/Fields/created",
"text": "The date a tiddler was created"
},
"$:/language/Docs/Fields/creator": {
"title": "$:/language/Docs/Fields/creator",
"text": "The name of the person who created a tiddler"
},
"$:/language/Docs/Fields/dependents": {
"title": "$:/language/Docs/Fields/dependents",
"text": "For a plugin, lists the dependent plugin titles"
},
"$:/language/Docs/Fields/description": {
"title": "$:/language/Docs/Fields/description",
"text": "The descriptive text for a plugin, or a modal dialogue"
},
"$:/language/Docs/Fields/draft.of": {
"title": "$:/language/Docs/Fields/draft.of",
"text": "For draft tiddlers, contains the title of the tiddler of which this is a draft"
},
"$:/language/Docs/Fields/draft.title": {
"title": "$:/language/Docs/Fields/draft.title",
"text": "For draft tiddlers, contains the proposed new title of the tiddler"
},
"$:/language/Docs/Fields/footer": {
"title": "$:/language/Docs/Fields/footer",
"text": "The footer text for a wizard"
},
"$:/language/Docs/Fields/hack-to-give-us-something-to-compare-against": {
"title": "$:/language/Docs/Fields/hack-to-give-us-something-to-compare-against",
"text": "A temporary storage field used in [[$:/core/templates/static.content]]"
},
"$:/language/Docs/Fields/icon": {
"title": "$:/language/Docs/Fields/icon",
"text": "The title of the tiddler containing the icon associated with a tiddler"
},
"$:/language/Docs/Fields/library": {
"title": "$:/language/Docs/Fields/library",
"text": "If set to \"yes\" indicates that a tiddler should be saved as a JavaScript library"
},
"$:/language/Docs/Fields/list": {
"title": "$:/language/Docs/Fields/list",
"text": "An ordered list of tiddler titles associated with a tiddler"
},
"$:/language/Docs/Fields/list-before": {
"title": "$:/language/Docs/Fields/list-before",
"text": "If set, the title of a tiddler before which this tiddler should be added to the ordered list of tiddler titles, or at the start of the list if this field is present but empty"
},
"$:/language/Docs/Fields/list-after": {
"title": "$:/language/Docs/Fields/list-after",
"text": "If set, the title of the tiddler after which this tiddler should be added to the ordered list of tiddler titles, or at the end of the list if this field is present but empty"
},
"$:/language/Docs/Fields/modified": {
"title": "$:/language/Docs/Fields/modified",
"text": "The date and time at which a tiddler was last modified"
},
"$:/language/Docs/Fields/modifier": {
"title": "$:/language/Docs/Fields/modifier",
"text": "The tiddler title associated with the person who last modified a tiddler"
},
"$:/language/Docs/Fields/name": {
"title": "$:/language/Docs/Fields/name",
"text": "The human readable name associated with a plugin tiddler"
},
"$:/language/Docs/Fields/plugin-priority": {
"title": "$:/language/Docs/Fields/plugin-priority",
"text": "A numerical value indicating the priority of a plugin tiddler"
},
"$:/language/Docs/Fields/plugin-type": {
"title": "$:/language/Docs/Fields/plugin-type",
"text": "The type of plugin in a plugin tiddler"
},
"$:/language/Docs/Fields/revision": {
"title": "$:/language/Docs/Fields/revision",
"text": "The revision of the tiddler held at the server"
},
"$:/language/Docs/Fields/released": {
"title": "$:/language/Docs/Fields/released",
"text": "Date of a TiddlyWiki release"
},
"$:/language/Docs/Fields/source": {
"title": "$:/language/Docs/Fields/source",
"text": "The source URL associated with a tiddler"
},
"$:/language/Docs/Fields/subtitle": {
"title": "$:/language/Docs/Fields/subtitle",
"text": "The subtitle text for a wizard"
},
"$:/language/Docs/Fields/tags": {
"title": "$:/language/Docs/Fields/tags",
"text": "A list of tags associated with a tiddler"
},
"$:/language/Docs/Fields/text": {
"title": "$:/language/Docs/Fields/text",
"text": "The body text of a tiddler"
},
"$:/language/Docs/Fields/title": {
"title": "$:/language/Docs/Fields/title",
"text": "The unique name of a tiddler"
},
"$:/language/Docs/Fields/type": {
"title": "$:/language/Docs/Fields/type",
"text": "The content type of a tiddler"
},
"$:/language/Docs/Fields/version": {
"title": "$:/language/Docs/Fields/version",
"text": "Version information for a plugin"
},
"$:/language/Filters/AllTiddlers": {
"title": "$:/language/Filters/AllTiddlers",
"text": "All tiddlers except system tiddlers"
},
"$:/language/Filters/RecentSystemTiddlers": {
"title": "$:/language/Filters/RecentSystemTiddlers",
"text": "Recently modified tiddlers, including system tiddlers"
},
"$:/language/Filters/RecentTiddlers": {
"title": "$:/language/Filters/RecentTiddlers",
"text": "Recently modified tiddlers"
},
"$:/language/Filters/AllTags": {
"title": "$:/language/Filters/AllTags",
"text": "All tags except system tags"
},
"$:/language/Filters/Missing": {
"title": "$:/language/Filters/Missing",
"text": "Missing tiddlers"
},
"$:/language/Filters/Drafts": {
"title": "$:/language/Filters/Drafts",
"text": "Draft tiddlers"
},
"$:/language/Filters/Orphans": {
"title": "$:/language/Filters/Orphans",
"text": "Orphan tiddlers"
},
"$:/language/Filters/SystemTiddlers": {
"title": "$:/language/Filters/SystemTiddlers",
"text": "System tiddlers"
},
"$:/language/Filters/ShadowTiddlers": {
"title": "$:/language/Filters/ShadowTiddlers",
"text": "Shadow tiddlers"
},
"$:/language/Filters/OverriddenShadowTiddlers": {
"title": "$:/language/Filters/OverriddenShadowTiddlers",
"text": "Overridden shadow tiddlers"
},
"$:/language/Filters/SystemTags": {
"title": "$:/language/Filters/SystemTags",
"text": "System tags"
},
"$:/language/Filters/StoryList": {
"title": "$:/language/Filters/StoryList",
"text": "Tiddlers in the story river, excluding <$text text=\"$:/AdvancedSearch\"/>"
},
"$:/language/Filters/TypedTiddlers": {
"title": "$:/language/Filters/TypedTiddlers",
"text": "Non wiki-text tiddlers"
},
"GettingStarted": {
"title": "GettingStarted",
"text": "\\define lingo-base() $:/language/ControlPanel/Basics/\nWelcome to ~TiddlyWiki and the ~TiddlyWiki community\n\nBefore you start storing important information in ~TiddlyWiki it is vital to make sure that you can reliably save changes. See https://tiddlywiki.com/#GettingStarted for details\n\n!! Set up this ~TiddlyWiki\n\n<div class=\"tc-control-panel\">\n\n|<$link to=\"$:/SiteTitle\"><<lingo Title/Prompt>></$link> |<$edit-text tiddler=\"$:/SiteTitle\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/SiteSubtitle\"><<lingo Subtitle/Prompt>></$link> |<$edit-text tiddler=\"$:/SiteSubtitle\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/DefaultTiddlers\"><<lingo DefaultTiddlers/Prompt>></$link> |<<lingo DefaultTiddlers/TopHint>><br> <$edit tag=\"textarea\" tiddler=\"$:/DefaultTiddlers\"/><br>//<<lingo DefaultTiddlers/BottomHint>>// |\n</div>\n\nSee the [[control panel|$:/ControlPanel]] for more options.\n"
},
"$:/language/Help/build": {
"title": "$:/language/Help/build",
"description": "Automatically run configured commands",
"text": "Build the specified build targets for the current wiki. If no build targets are specified then all available targets will be built.\n\n```\n--build <target> [<target> ...]\n```\n\nBuild targets are defined in the `tiddlywiki.info` file of a wiki folder.\n\n"
},
"$:/language/Help/clearpassword": {
"title": "$:/language/Help/clearpassword",
"description": "Clear a password for subsequent crypto operations",
"text": "Clear the password for subsequent crypto operations\n\n```\n--clearpassword\n```\n"
},
"$:/language/Help/default": {
"title": "$:/language/Help/default",
"text": "\\define commandTitle()\n$:/language/Help/$(command)$\n\\end\n```\nusage: tiddlywiki [<wikifolder>] [--<command> [<args>...]...]\n```\n\nAvailable commands:\n\n<ul>\n<$list filter=\"[commands[]sort[title]]\" variable=\"command\">\n<li><$link to=<<commandTitle>>><$macrocall $name=\"command\" $type=\"text/plain\" $output=\"text/plain\"/></$link>: <$transclude tiddler=<<commandTitle>> field=\"description\"/></li>\n</$list>\n</ul>\n\nTo get detailed help on a command:\n\n```\ntiddlywiki --help <command>\n```\n"
},
"$:/language/Help/editions": {
"title": "$:/language/Help/editions",
"description": "Lists the available editions of TiddlyWiki",
"text": "Lists the names and descriptions of the available editions. You can create a new wiki of a specified edition with the `--init` command.\n\n```\n--editions\n```\n"
},
"$:/language/Help/fetch": {
"title": "$:/language/Help/fetch",
"description": "Fetch tiddlers from wiki by URL",
"text": "Fetch one or more files over HTTP/HTTPS, and import the tiddlers matching a filter, optionally transforming the incoming titles.\n\n```\n--fetch file <url> <import-filter> <transform-filter>\n--fetch files <url-filter> <import-filter> <transform-filter>\n--fetch raw-file <url> <transform-filter>\n--fetch raw-files <url-filter> <transform-filter>\n```\n\nThe \"file\" and \"files\" variants fetch the specified files and attempt to import the tiddlers within them (the same processing as if the files were dragged into the browser window). The \"raw-file\" and \"raw-files\" variants fetch the specified files and then store the raw file data in tiddlers, without applying the import logic.\n\nWith the \"file\" and \"raw-file\" variants only a single file is fetched and the first parameter is the URL of the file to read.\n\nWith the \"files\" and \"raw-files\" variants, multiple files are fetched and the first parameter is a filter yielding a list of URLs of the files to read. For example, given a set of tiddlers tagged \"remote-server\" that have a field \"url\" the filter `[tag[remote-server]get[url]]` will retrieve all the available URLs.\n\nFor the \"file\" and \"files\" variants, the `<import-filter>` parameter specifies a filter determining which tiddlers are imported. It defaults to `[all[tiddlers]]` if not provided.\n\nFor all variants, the `<transform-filter>` parameter specifies an optional filter that transforms the titles of the imported tiddlers. For example, `[addprefix[$:/myimports/]]` would add the prefix `$:/myimports/` to each title.\n\nPreceding the `--fetch` command with `--verbose` will output progress information during the import.\n\nNote that TiddlyWiki will not fetch an older version of an already loaded plugin.\n\nThe following example retrieves all the non-system tiddlers from https://tiddlywiki.com and saves them to a JSON file:\n\n```\ntiddlywiki --verbose --fetch file \"https://tiddlywiki.com/\" \"[!is[system]]\" \"\" --rendertiddler \"$:/core/templates/exporters/JsonFile\" output.json text/plain \"\" exportFilter \"[!is[system]]\"\n```\n\nThe following example retrieves the \"favicon\" file from tiddlywiki.com and saves it in a file called \"output.ico\". Note that the intermediate tiddler \"Icon Tiddler\" is quoted in the \"--fetch\" command because it is being used as a transformation filter to replace the default title, while there are no quotes for the \"--savetiddler\" command because it is being used directly as a title.\n\n```\ntiddlywiki --verbose --fetch raw-file \"https://tiddlywiki.com/favicon.ico\" \"[[Icon Tiddler]]\" --savetiddler \"Icon Tiddler\" output.ico\n```\n\n"
},
"$:/language/Help/help": {
"title": "$:/language/Help/help",
"description": "Display help for TiddlyWiki commands",
"text": "Displays help text for a command:\n\n```\n--help [<command>]\n```\n\nIf the command name is omitted then a list of available commands is displayed.\n"
},
"$:/language/Help/import": {
"title": "$:/language/Help/import",
"description": "Import tiddlers from a file",
"text": "Import tiddlers from TiddlyWiki (`.html`), `.tiddler`, `.tid`, `.json` or other local files. The deserializer must be explicitly specified, unlike the `load` command which infers the deserializer from the file extension.\n\n```\n--import <filepath> <deserializer> [<title>] [<encoding>]\n```\n\nThe deserializers in the core include:\n\n* application/javascript\n* application/json\n* application/x-tiddler\n* application/x-tiddler-html-div\n* application/x-tiddlers\n* text/html\n* text/plain\n\nThe title of the imported tiddler defaults to the filename.\n\nThe encoding defaults to \"utf8\", but can be \"base64\" for importing binary files.\n\nNote that TiddlyWiki will not import an older version of an already loaded plugin.\n"
},
"$:/language/Help/init": {
"title": "$:/language/Help/init",
"description": "Initialise a new wiki folder",
"text": "Initialise an empty [[WikiFolder|WikiFolders]] with a copy of the specified edition.\n\n```\n--init <edition> [<edition> ...]\n```\n\nFor example:\n\n```\ntiddlywiki ./MyWikiFolder --init empty\n```\n\nNote:\n\n* The wiki folder directory will be created if necessary\n* The \"edition\" defaults to ''empty''\n* The init command will fail if the wiki folder is not empty\n* The init command removes any `includeWikis` definitions in the edition's `tiddlywiki.info` file\n* When multiple editions are specified, editions initialised later will overwrite any files shared with earlier editions (so, the final `tiddlywiki.info` file will be copied from the last edition)\n* `--editions` returns a list of available editions\n"
},
"$:/language/Help/listen": {
"title": "$:/language/Help/listen",
"description": "Provides an HTTP server interface to TiddlyWiki",
"text": "Serves a wiki over HTTP.\n\nThe listen command uses NamedCommandParameters:\n\n```\n--listen [<name>=<value>]...\n```\n\nAll parameters are optional with safe defaults, and can be specified in any order. The recognised parameters are:\n\n* ''host'' - optional hostname to serve from (defaults to \"127.0.0.1\" aka \"localhost\")\n* ''path-prefix'' - optional prefix for paths\n* ''port'' - port number on which to listen; non-numeric values are interpreted as a system environment variable from which the port number is extracted (defaults to \"8080\")\n* ''credentials'' - pathname of credentials CSV file (relative to wiki folder)\n* ''anon-username'' - the username for signing edits for anonymous users\n* ''username'' - optional username for basic authentication\n* ''password'' - optional password for basic authentication\n* ''authenticated-user-header'' - optional name of header to be used for trusted authentication\n* ''readers'' - comma separated list of principals allowed to read from this wiki\n* ''writers'' - comma separated list of principals allowed to write to this wiki\n* ''csrf-disable'' - set to \"yes\" to disable CSRF checks (defaults to \"no\")\n* ''root-tiddler'' - the tiddler to serve at the root (defaults to \"$:/core/save/all\")\n* ''root-render-type'' - the content type to which the root tiddler should be rendered (defaults to \"text/plain\")\n* ''root-serve-type'' - the content type with which the root tiddler should be served (defaults to \"text/html\")\n* ''tls-cert'' - pathname of TLS certificate file (relative to wiki folder)\n* ''tls-key'' - pathname of TLS key file (relative to wiki folder)\n* ''debug-level'' - optional debug level; set to \"debug\" to view request details (defaults to \"none\")\n\nFor information on opening up your instance to the entire local network, and possible security concerns, see the WebServer tiddler at TiddlyWiki.com.\n\n"
},
"$:/language/Help/load": {
"title": "$:/language/Help/load",
"description": "Load tiddlers from a file",
"text": "Load tiddlers from TiddlyWiki (`.html`), `.tiddler`, `.tid`, `.json` or other local files. The processing applied to incoming files is determined by the file extension. Use the alternative `import` command if you need to specify the deserializer and encoding explicitly.\n\n```\n--load <filepath>\n--load <dirpath>\n```\n\nTo load tiddlers from an encrypted TiddlyWiki file you should first specify the password with the PasswordCommand. For example:\n\n```\ntiddlywiki ./MyWiki --password pa55w0rd --load my_encrypted_wiki.html\n```\n\nNote that TiddlyWiki will not load an older version of an already loaded plugin.\n"
},
"$:/language/Help/makelibrary": {
"title": "$:/language/Help/makelibrary",
"description": "Construct library plugin required by upgrade process",
"text": "Constructs the `$:/UpgradeLibrary` tiddler for the upgrade process.\n\nThe upgrade library is formatted as an ordinary plugin tiddler with the plugin type `library`. It contains a copy of each of the plugins, themes and language packs available within the TiddlyWiki5 repository.\n\nThis command is intended for internal use; it is only relevant to users constructing a custom upgrade procedure.\n\n```\n--makelibrary <title>\n```\n\nThe title argument defaults to `$:/UpgradeLibrary`.\n"
},
"$:/language/Help/notfound": {
"title": "$:/language/Help/notfound",
"text": "No such help item"
},
"$:/language/Help/output": {
"title": "$:/language/Help/output",
"description": "Set the base output directory for subsequent commands",
"text": "Sets the base output directory for subsequent commands. The default output directory is the `output` subdirectory of the edition directory.\n\n```\n--output <pathname>\n```\n\nIf the specified pathname is relative then it is resolved relative to the current working directory. For example `--output .` sets the output directory to the current working directory.\n\n"
},
"$:/language/Help/password": {
"title": "$:/language/Help/password",
"description": "Set a password for subsequent crypto operations",
"text": "Set a password for subsequent crypto operations\n\n```\n--password <password>\n```\n\n''Note'': This should not be used for serving TiddlyWiki with password protection. Instead, see the password option under the [[ServerCommand]].\n"
},
"$:/language/Help/render": {
"title": "$:/language/Help/render",
"description": "Renders individual tiddlers to files",
"text": "Render individual tiddlers identified by a filter and save the results to the specified files.\n\nOptionally, the title of a template tiddler can be specified. In this case, instead of directly rendering each tiddler, the template tiddler is rendered with the \"currentTiddler\" variable set to the title of the tiddler that is being rendered.\n\nA name and value for an additional variable may optionally also be specified.\n\n```\n--render <tiddler-filter> [<filename-filter>] [<render-type>] [<template>] [<name>] [<value>]\n```\n\n* ''tiddler-filter'': A filter identifying the tiddler(s) to be rendered\n* ''filename-filter'': Optional filter transforming tiddler titles into pathnames. If omitted, defaults to `[is[tiddler]addsuffix[.html]]`, which uses the unchanged tiddler title as the filename\n* ''template'': Optional template through which each tiddler is rendered\n* ''render-type'': Optional render type: `text/html` (the default) returns the full HTML text and `text/plain` just returns the text content (ie it ignores HTML tags and other unprintable material)\n* ''name'': Name of optional variable\n* ''value'': Value of optional variable\n\nBy default, the filename is resolved relative to the `output` subdirectory of the edition directory. The `--output` command can be used to direct output to a different directory.\n\nNotes:\n\n* The output directory is not cleared of any existing files\n* Any missing directories in the path to the filename are automatically created.\n* When referring to a tiddler with spaces in its title, take care to use both the quotes required by your shell and also TiddlyWiki's double square brackets : `--render \"[[Motovun Jack.jpg]]\"`\n* The filename filter is evaluated with the selected items being set to the title of the tiddler currently being rendered, allowing the title to be used as the basis for computing the filename. For example `[encodeuricomponent[]addprefix[static/]]` applies URI encoding to each title, and then adds the prefix `static/`\n* The `--render` command is a more flexible replacement for both the `--rendertiddler` and `--rendertiddlers` commands, which are deprecated\n\nExamples:\n\n* `--render \"[!is[system]]\" \"[encodeuricomponent[]addprefix[tiddlers/]addsuffix[.html]]\"` -- renders all non-system tiddlers as files in the subdirectory \"tiddlers\" with URL-encoded titles and the extension HTML\n\n"
},
"$:/language/Help/rendertiddler": {
"title": "$:/language/Help/rendertiddler",
"description": "Render an individual tiddler as a specified ContentType",
"text": "(Note: The `--rendertiddler` command is deprecated in favour of the new, more flexible `--render` command)\n\nRender an individual tiddler as a specified ContentType, defaulting to `text/html` and save it to the specified filename.\n\nOptionally the title of a template tiddler can be specified, in which case the template tiddler is rendered with the \"currentTiddler\" variable set to the tiddler that is being rendered (the first parameter value).\n\nA name and value for an additional variable may optionally also be specified.\n\n```\n--rendertiddler <title> <filename> [<type>] [<template>] [<name>] [<value>]\n```\n\nBy default, the filename is resolved relative to the `output` subdirectory of the edition directory. The `--output` command can be used to direct output to a different directory.\n\nAny missing directories in the path to the filename are automatically created.\n\nFor example, the following command saves all tiddlers matching the filter `[tag[done]]` to a JSON file titled `output.json` by employing the core template `$:/core/templates/exporters/JsonFile`.\n\n```\n--rendertiddler \"$:/core/templates/exporters/JsonFile\" output.json text/plain \"\" exportFilter \"[tag[done]]\"\n```\n"
},
"$:/language/Help/rendertiddlers": {
"title": "$:/language/Help/rendertiddlers",
"description": "Render tiddlers matching a filter to a specified ContentType",
"text": "(Note: The `--rendertiddlers` command is deprecated in favour of the new, more flexible `--render` command)\n\nRender a set of tiddlers matching a filter to separate files of a specified ContentType (defaults to `text/html`) and extension (defaults to `.html`).\n\n```\n--rendertiddlers <filter> <template> <pathname> [<type>] [<extension>] [\"noclean\"]\n```\n\nFor example:\n\n```\n--rendertiddlers [!is[system]] $:/core/templates/static.tiddler.html ./static text/plain\n```\n\nBy default, the pathname is resolved relative to the `output` subdirectory of the edition directory. The `--output` command can be used to direct output to a different directory.\n\nAny files in the target directory are deleted unless the ''noclean'' flag is specified. The target directory is recursively created if it is missing.\n"
},
"$:/language/Help/save": {
"title": "$:/language/Help/save",
"description": "Saves individual raw tiddlers to files",
"text": "Saves individual tiddlers identified by a filter in their raw text or binary format to the specified files.\n\n```\n--save <tiddler-filter> <filename-filter>\n```\n\n* ''tiddler-filter'': A filter identifying the tiddler(s) to be saved\n* ''filename-filter'': Optional filter transforming tiddler titles into pathnames. If omitted, defaults to `[is[tiddler]]`, which uses the unchanged tiddler title as the filename\n\nBy default, the filename is resolved relative to the `output` subdirectory of the edition directory. The `--output` command can be used to direct output to a different directory.\n\nNotes:\n\n* The output directory is not cleared of any existing files\n* Any missing directories in the path to the filename are automatically created.\n* When saving a tiddler with spaces in its title, take care to use both the quotes required by your shell and also TiddlyWiki's double square brackets : `--save \"[[Motovun Jack.jpg]]\"`\n* The filename filter is evaluated with the selected items being set to the title of the tiddler currently being saved, allowing the title to be used as the basis for computing the filename. For example `[encodeuricomponent[]addprefix[static/]]` applies URI encoding to each title, and then adds the prefix `static/`\n* The `--save` command is a more flexible replacement for both the `--savetiddler` and `--savetiddlers` commands, which are deprecated\n\nExamples:\n\n* `--save \"[!is[system]is[image]]\" \"[encodeuricomponent[]addprefix[tiddlers/]]\"` -- saves all non-system image tiddlers as files in the subdirectory \"tiddlers\" with URL-encoded titles\n"
},
"$:/language/Help/savetiddler": {
"title": "$:/language/Help/savetiddler",
"description": "Saves a raw tiddler to a file",
"text": "(Note: The `--savetiddler` command is deprecated in favour of the new, more flexible `--save` command)\n\nSaves an individual tiddler in its raw text or binary format to the specified filename.\n\n```\n--savetiddler <title> <filename>\n```\n\nBy default, the filename is resolved relative to the `output` subdirectory of the edition directory. The `--output` command can be used to direct output to a different directory.\n\nAny missing directories in the path to the filename are automatically created.\n"
},
"$:/language/Help/savetiddlers": {
"title": "$:/language/Help/savetiddlers",
"description": "Saves a group of raw tiddlers to a directory",
"text": "(Note: The `--savetiddlers` command is deprecated in favour of the new, more flexible `--save` command)\n\nSaves a group of tiddlers in their raw text or binary format to the specified directory.\n\n```\n--savetiddlers <filter> <pathname> [\"noclean\"]\n```\n\nBy default, the pathname is resolved relative to the `output` subdirectory of the edition directory. The `--output` command can be used to direct output to a different directory.\n\nThe output directory is cleared of existing files before saving the specified files. The deletion can be disabled by specifying the ''noclean'' flag.\n\nAny missing directories in the pathname are automatically created.\n"
},
"$:/language/Help/server": {
"title": "$:/language/Help/server",
"description": "Provides an HTTP server interface to TiddlyWiki (deprecated in favour of the new listen command)",
"text": "Legacy command to serve a wiki over HTTP.\n\n```\n--server <port> <root-tiddler> <root-render-type> <root-serve-type> <username> <password> <host> <path-prefix> <debug-level>\n```\n\nThe parameters are:\n\n* ''port'' - port number on which to listen; non-numeric values are interpreted as a system environment variable from which the port number is extracted (defaults to \"8080\")\n* ''root-tiddler'' - the tiddler to serve at the root (defaults to \"$:/core/save/all\")\n* ''root-render-type'' - the content type to which the root tiddler should be rendered (defaults to \"text/plain\")\n* ''root-serve-type'' - the content type with which the root tiddler should be served (defaults to \"text/html\")\n* ''username'' - the default username for signing edits\n* ''password'' - optional password for basic authentication\n* ''host'' - optional hostname to serve from (defaults to \"127.0.0.1\" aka \"localhost\")\n* ''path-prefix'' - optional prefix for paths\n* ''debug-level'' - optional debug level; set to \"debug\" to view request details (defaults to \"none\")\n\nIf the password parameter is specified then the browser will prompt the user for the username and password. Note that the password is transmitted in plain text so this implementation should only be used on a trusted network or over HTTPS.\n\nFor example:\n\n```\n--server 8080 $:/core/save/all text/plain text/html MyUserName passw0rd\n```\n\nThe username and password can be specified as empty strings if you need to set the hostname or pathprefix and don't want to require a password.\n\n\n```\n--server 8080 $:/core/save/all text/plain text/html \"\" \"\" 192.168.0.245\n```\n\nUsing an address like this exposes your system to the local network. For information on opening up your instance to the entire local network, and possible security concerns, see the WebServer tiddler at TiddlyWiki.com.\n\nTo run multiple TiddlyWiki servers at the same time you'll need to put each one on a different port. It can be useful to use an environment variable to pass the port number to the Node.js process. This example references an environment variable called \"MY_PORT_NUMBER\":\n\n```\n--server MY_PORT_NUMBER $:/core/save/all text/plain text/html MyUserName passw0rd\n```\n"
},
"$:/language/Help/setfield": {
"title": "$:/language/Help/setfield",
"description": "Prepares external tiddlers for use",
"text": "//Note that this command is experimental and may change or be replaced before being finalised//\n\nSets the specified field of a group of tiddlers to the result of wikifying a template tiddler with the `currentTiddler` variable set to the tiddler.\n\n```\n--setfield <filter> <fieldname> <templatetitle> <rendertype>\n```\n\nThe parameters are:\n\n* ''filter'' - filter identifying the tiddlers to be affected\n* ''fieldname'' - the field to modify (defaults to \"text\")\n* ''templatetitle'' - the tiddler to wikify into the specified field. If blank or missing then the specified field is deleted\n* ''rendertype'' - the text type to render (defaults to \"text/plain\"; \"text/html\" can be used to include HTML tags)\n"
},
"$:/language/Help/unpackplugin": {
"title": "$:/language/Help/unpackplugin",
"description": "Unpack the payload tiddlers from a plugin",
"text": "Extract the payload tiddlers from a plugin, creating them as ordinary tiddlers:\n\n```\n--unpackplugin <title>\n```\n"
},
"$:/language/Help/verbose": {
"title": "$:/language/Help/verbose",
"description": "Triggers verbose output mode",
"text": "Triggers verbose output, useful for debugging\n\n```\n--verbose\n```\n"
},
"$:/language/Help/version": {
"title": "$:/language/Help/version",
"description": "Displays the version number of TiddlyWiki",
"text": "Displays the version number of TiddlyWiki.\n\n```\n--version\n```\n"
},
"$:/language/Import/Imported/Hint": {
"title": "$:/language/Import/Imported/Hint",
"text": "The following tiddlers were imported:"
},
"$:/language/Import/Listing/Cancel/Caption": {
"title": "$:/language/Import/Listing/Cancel/Caption",
"text": "Cancel"
},
"$:/language/Import/Listing/Hint": {
"title": "$:/language/Import/Listing/Hint",
"text": "These tiddlers are ready to import:"
},
"$:/language/Import/Listing/Import/Caption": {
"title": "$:/language/Import/Listing/Import/Caption",
"text": "Import"
},
"$:/language/Import/Listing/Select/Caption": {
"title": "$:/language/Import/Listing/Select/Caption",
"text": "Select"
},
"$:/language/Import/Listing/Status/Caption": {
"title": "$:/language/Import/Listing/Status/Caption",
"text": "Status"
},
"$:/language/Import/Listing/Title/Caption": {
"title": "$:/language/Import/Listing/Title/Caption",
"text": "Title"
},
"$:/language/Import/Listing/Preview": {
"title": "$:/language/Import/Listing/Preview",
"text": "Preview:"
},
"$:/language/Import/Listing/Preview/Text": {
"title": "$:/language/Import/Listing/Preview/Text",
"text": "Text"
},
"$:/language/Import/Listing/Preview/TextRaw": {
"title": "$:/language/Import/Listing/Preview/TextRaw",
"text": "Text (Raw)"
},
"$:/language/Import/Listing/Preview/Fields": {
"title": "$:/language/Import/Listing/Preview/Fields",
"text": "Fields"
},
"$:/language/Import/Listing/Preview/Diff": {
"title": "$:/language/Import/Listing/Preview/Diff",
"text": "Diff"
},
"$:/language/Import/Listing/Preview/DiffFields": {
"title": "$:/language/Import/Listing/Preview/DiffFields",
"text": "Diff (Fields)"
},
"$:/language/Import/Upgrader/Plugins/Suppressed/Incompatible": {
"title": "$:/language/Import/Upgrader/Plugins/Suppressed/Incompatible",
"text": "Blocked incompatible or obsolete plugin"
},
"$:/language/Import/Upgrader/Plugins/Suppressed/Version": {
"title": "$:/language/Import/Upgrader/Plugins/Suppressed/Version",
"text": "Blocked plugin (due to incoming <<incoming>> being older than existing <<existing>>)"
},
"$:/language/Import/Upgrader/Plugins/Upgraded": {
"title": "$:/language/Import/Upgrader/Plugins/Upgraded",
"text": "Upgraded plugin from <<incoming>> to <<upgraded>>"
},
"$:/language/Import/Upgrader/State/Suppressed": {
"title": "$:/language/Import/Upgrader/State/Suppressed",
"text": "Blocked temporary state tiddler"
},
"$:/language/Import/Upgrader/System/Suppressed": {
"title": "$:/language/Import/Upgrader/System/Suppressed",
"text": "Blocked system tiddler"
},
"$:/language/Import/Upgrader/ThemeTweaks/Created": {
"title": "$:/language/Import/Upgrader/ThemeTweaks/Created",
"text": "Migrated theme tweak from <$text text=<<from>>/>"
},
"$:/language/AboveStory/ClassicPlugin/Warning": {
"title": "$:/language/AboveStory/ClassicPlugin/Warning",
"text": "It looks like you are trying to load a plugin designed for ~TiddlyWiki Classic. Please note that [[these plugins do not work with TiddlyWiki version 5.x.x|https://tiddlywiki.com/#TiddlyWikiClassic]]. ~TiddlyWiki Classic plugins detected:"
},
"$:/language/BinaryWarning/Prompt": {
"title": "$:/language/BinaryWarning/Prompt",
"text": "This tiddler contains binary data"
},
"$:/language/ClassicWarning/Hint": {
"title": "$:/language/ClassicWarning/Hint",
"text": "This tiddler is written in TiddlyWiki Classic wiki text format, which is not fully compatible with TiddlyWiki version 5. See https://tiddlywiki.com/static/Upgrading.html for more details."
},
"$:/language/ClassicWarning/Upgrade/Caption": {
"title": "$:/language/ClassicWarning/Upgrade/Caption",
"text": "upgrade"
},
"$:/language/CloseAll/Button": {
"title": "$:/language/CloseAll/Button",
"text": "close all"
},
"$:/language/ColourPicker/Recent": {
"title": "$:/language/ColourPicker/Recent",
"text": "Recent:"
},
"$:/language/ConfirmCancelTiddler": {
"title": "$:/language/ConfirmCancelTiddler",
"text": "Do you wish to discard changes to the tiddler \"<$text text=<<title>>/>\"?"
},
"$:/language/ConfirmDeleteTiddler": {
"title": "$:/language/ConfirmDeleteTiddler",
"text": "Do you wish to delete the tiddler \"<$text text=<<title>>/>\"?"
},
"$:/language/ConfirmOverwriteTiddler": {
"title": "$:/language/ConfirmOverwriteTiddler",
"text": "Do you wish to overwrite the tiddler \"<$text text=<<title>>/>\"?"
},
"$:/language/ConfirmEditShadowTiddler": {
"title": "$:/language/ConfirmEditShadowTiddler",
"text": "You are about to edit a ShadowTiddler. Any changes will override the default system making future upgrades non-trivial. Are you sure you want to edit \"<$text text=<<title>>/>\"?"
},
"$:/language/Count": {
"title": "$:/language/Count",
"text": "count"
},
"$:/language/DefaultNewTiddlerTitle": {
"title": "$:/language/DefaultNewTiddlerTitle",
"text": "New Tiddler"
},
"$:/language/Diffs/CountMessage": {
"title": "$:/language/Diffs/CountMessage",
"text": "<<diff-count>> differences"
},
"$:/language/DropMessage": {
"title": "$:/language/DropMessage",
"text": "Drop here (or use the 'Escape' key to cancel)"
},
"$:/language/Encryption/Cancel": {
"title": "$:/language/Encryption/Cancel",
"text": "Cancel"
},
"$:/language/Encryption/ConfirmClearPassword": {
"title": "$:/language/Encryption/ConfirmClearPassword",
"text": "Do you wish to clear the password? This will remove the encryption applied when saving this wiki"
},
"$:/language/Encryption/PromptSetPassword": {
"title": "$:/language/Encryption/PromptSetPassword",
"text": "Set a new password for this TiddlyWiki"
},
"$:/language/Encryption/Username": {
"title": "$:/language/Encryption/Username",
"text": "Username"
},
"$:/language/Encryption/Password": {
"title": "$:/language/Encryption/Password",
"text": "Password"
},
"$:/language/Encryption/RepeatPassword": {
"title": "$:/language/Encryption/RepeatPassword",
"text": "Repeat password"
},
"$:/language/Encryption/PasswordNoMatch": {
"title": "$:/language/Encryption/PasswordNoMatch",
"text": "Passwords do not match"
},
"$:/language/Encryption/SetPassword": {
"title": "$:/language/Encryption/SetPassword",
"text": "Set password"
},
"$:/language/Error/Caption": {
"title": "$:/language/Error/Caption",
"text": "Error"
},
"$:/language/Error/EditConflict": {
"title": "$:/language/Error/EditConflict",
"text": "File changed on server"
},
"$:/language/Error/Filter": {
"title": "$:/language/Error/Filter",
"text": "Filter error"
},
"$:/language/Error/FilterSyntax": {
"title": "$:/language/Error/FilterSyntax",
"text": "Syntax error in filter expression"
},
"$:/language/Error/IsFilterOperator": {
"title": "$:/language/Error/IsFilterOperator",
"text": "Filter Error: Unknown operand for the 'is' filter operator"
},
"$:/language/Error/LoadingPluginLibrary": {
"title": "$:/language/Error/LoadingPluginLibrary",
"text": "Error loading plugin library"
},
"$:/language/Error/RecursiveTransclusion": {
"title": "$:/language/Error/RecursiveTransclusion",
"text": "Recursive transclusion error in transclude widget"
},
"$:/language/Error/RetrievingSkinny": {
"title": "$:/language/Error/RetrievingSkinny",
"text": "Error retrieving skinny tiddler list"
},
"$:/language/Error/SavingToTWEdit": {
"title": "$:/language/Error/SavingToTWEdit",
"text": "Error saving to TWEdit"
},
"$:/language/Error/WhileSaving": {
"title": "$:/language/Error/WhileSaving",
"text": "Error while saving"
},
"$:/language/Error/XMLHttpRequest": {
"title": "$:/language/Error/XMLHttpRequest",
"text": "XMLHttpRequest error code"
},
"$:/language/InternalJavaScriptError/Title": {
"title": "$:/language/InternalJavaScriptError/Title",
"text": "Internal JavaScript Error"
},
"$:/language/InternalJavaScriptError/Hint": {
"title": "$:/language/InternalJavaScriptError/Hint",
"text": "Well, this is embarrassing. It is recommended that you restart TiddlyWiki by refreshing your browser"
},
"$:/language/InvalidFieldName": {
"title": "$:/language/InvalidFieldName",
"text": "Illegal characters in field name \"<$text text=<<fieldName>>/>\". Fields can only contain lowercase letters, digits and the characters underscore (`_`), hyphen (`-`) and period (`.`)"
},
"$:/language/LazyLoadingWarning": {
"title": "$:/language/LazyLoadingWarning",
"text": "<p>Trying to load external content from ''<$text text={{!!_canonical_uri}}/>''</p><p>If this message doesn't disappear, either the tiddler content type doesn't match the type of the external content, or you may be using a browser that doesn't support external content for wikis loaded as standalone files. See https://tiddlywiki.com/#ExternalText</p>"
},
"$:/language/LoginToTiddlySpace": {
"title": "$:/language/LoginToTiddlySpace",
"text": "Login to TiddlySpace"
},
"$:/language/Manager/Controls/FilterByTag/None": {
"title": "$:/language/Manager/Controls/FilterByTag/None",
"text": "(none)"
},
"$:/language/Manager/Controls/FilterByTag/Prompt": {
"title": "$:/language/Manager/Controls/FilterByTag/Prompt",
"text": "Filter by tag:"
},
"$:/language/Manager/Controls/Order/Prompt": {
"title": "$:/language/Manager/Controls/Order/Prompt",
"text": "Reverse order"
},
"$:/language/Manager/Controls/Search/Placeholder": {
"title": "$:/language/Manager/Controls/Search/Placeholder",
"text": "Search"
},
"$:/language/Manager/Controls/Search/Prompt": {
"title": "$:/language/Manager/Controls/Search/Prompt",
"text": "Search:"
},
"$:/language/Manager/Controls/Show/Option/Tags": {
"title": "$:/language/Manager/Controls/Show/Option/Tags",
"text": "tags"
},
"$:/language/Manager/Controls/Show/Option/Tiddlers": {
"title": "$:/language/Manager/Controls/Show/Option/Tiddlers",
"text": "tiddlers"
},
"$:/language/Manager/Controls/Show/Prompt": {
"title": "$:/language/Manager/Controls/Show/Prompt",
"text": "Show:"
},
"$:/language/Manager/Controls/Sort/Prompt": {
"title": "$:/language/Manager/Controls/Sort/Prompt",
"text": "Sort by:"
},
"$:/language/Manager/Item/Colour": {
"title": "$:/language/Manager/Item/Colour",
"text": "Colour"
},
"$:/language/Manager/Item/Fields": {
"title": "$:/language/Manager/Item/Fields",
"text": "Fields"
},
"$:/language/Manager/Item/Icon/None": {
"title": "$:/language/Manager/Item/Icon/None",
"text": "(none)"
},
"$:/language/Manager/Item/Icon": {
"title": "$:/language/Manager/Item/Icon",
"text": "Icon"
},
"$:/language/Manager/Item/RawText": {
"title": "$:/language/Manager/Item/RawText",
"text": "Raw text"
},
"$:/language/Manager/Item/Tags": {
"title": "$:/language/Manager/Item/Tags",
"text": "Tags"
},
"$:/language/Manager/Item/Tools": {
"title": "$:/language/Manager/Item/Tools",
"text": "Tools"
},
"$:/language/Manager/Item/WikifiedText": {
"title": "$:/language/Manager/Item/WikifiedText",
"text": "Wikified text"
},
"$:/language/MissingTiddler/Hint": {
"title": "$:/language/MissingTiddler/Hint",
"text": "Missing tiddler \"<$text text=<<currentTiddler>>/>\" -- click {{||$:/core/ui/Buttons/edit}} to create"
},
"$:/language/No": {
"title": "$:/language/No",
"text": "No"
},
"$:/language/OfficialPluginLibrary": {
"title": "$:/language/OfficialPluginLibrary",
"text": "Official ~TiddlyWiki Plugin Library"
},
"$:/language/OfficialPluginLibrary/Hint": {
"title": "$:/language/OfficialPluginLibrary/Hint",
"text": "The official ~TiddlyWiki plugin library at tiddlywiki.com. Plugins, themes and language packs are maintained by the core team."
},
"$:/language/PluginReloadWarning": {
"title": "$:/language/PluginReloadWarning",
"text": "Please save {{$:/core/ui/Buttons/save-wiki}} and reload {{$:/core/ui/Buttons/refresh}} to allow changes to plugins to take effect"
},
"$:/language/RecentChanges/DateFormat": {
"title": "$:/language/RecentChanges/DateFormat",
"text": "DDth MMM YYYY"
},
"$:/language/SystemTiddler/Tooltip": {
"title": "$:/language/SystemTiddler/Tooltip",
"text": "This is a system tiddler"
},
"$:/language/SystemTiddlers/Include/Prompt": {
"title": "$:/language/SystemTiddlers/Include/Prompt",
"text": "Include system tiddlers"
},
"$:/language/TagManager/Colour/Heading": {
"title": "$:/language/TagManager/Colour/Heading",
"text": "Colour"
},
"$:/language/TagManager/Count/Heading": {
"title": "$:/language/TagManager/Count/Heading",
"text": "Count"
},
"$:/language/TagManager/Icon/Heading": {
"title": "$:/language/TagManager/Icon/Heading",
"text": "Icon"
},
"$:/language/TagManager/Info/Heading": {
"title": "$:/language/TagManager/Info/Heading",
"text": "Info"
},
"$:/language/TagManager/Tag/Heading": {
"title": "$:/language/TagManager/Tag/Heading",
"text": "Tag"
},
"$:/language/Tiddler/DateFormat": {
"title": "$:/language/Tiddler/DateFormat",
"text": "DDth MMM YYYY at hh12:0mmam"
},
"$:/language/UnsavedChangesWarning": {
"title": "$:/language/UnsavedChangesWarning",
"text": "You have unsaved changes in TiddlyWiki"
},
"$:/language/Yes": {
"title": "$:/language/Yes",
"text": "Yes"
},
"$:/language/Modals/Download": {
"title": "$:/language/Modals/Download",
"subtitle": "Download changes",
"footer": "<$button message=\"tm-close-tiddler\">Close</$button>",
"help": "https://tiddlywiki.com/static/DownloadingChanges.html",
"text": "Your browser only supports manual saving.\n\nTo save your modified wiki, right click on the download link below and select \"Download file\" or \"Save file\", and then choose the folder and filename.\n\n//You can marginally speed things up by clicking the link with the control key (Windows) or the options/alt key (Mac OS X). You will not be prompted for the folder or filename, but your browser is likely to give it an unrecognisable name -- you may need to rename the file to include an `.html` extension before you can do anything useful with it.//\n\nOn smartphones that do not allow files to be downloaded you can instead bookmark the link, and then sync your bookmarks to a desktop computer from where the wiki can be saved normally.\n"
},
"$:/language/Modals/SaveInstructions": {
"title": "$:/language/Modals/SaveInstructions",
"subtitle": "Save your work",
"footer": "<$button message=\"tm-close-tiddler\">Close</$button>",
"help": "https://tiddlywiki.com/static/SavingChanges.html",
"text": "Your changes to this wiki need to be saved as a ~TiddlyWiki HTML file.\n\n!!! Desktop browsers\n\n# Select ''Save As'' from the ''File'' menu\n# Choose a filename and location\n#* Some browsers also require you to explicitly specify the file saving format as ''Webpage, HTML only'' or similar\n# Close this tab\n\n!!! Smartphone browsers\n\n# Create a bookmark to this page\n#* If you've got iCloud or Google Sync set up then the bookmark will automatically sync to your desktop where you can open it and save it as above\n# Close this tab\n\n//If you open the bookmark again in Mobile Safari you will see this message again. If you want to go ahead and use the file, just click the ''close'' button below//\n"
},
"$:/config/NewJournal/Title": {
"title": "$:/config/NewJournal/Title",
"text": "DDth MMM YYYY"
},
"$:/config/NewJournal/Text": {
"title": "$:/config/NewJournal/Text",
"text": ""
},
"$:/config/NewJournal/Tags": {
"title": "$:/config/NewJournal/Tags",
"text": "Journal"
},
"$:/language/Notifications/Save/Done": {
"title": "$:/language/Notifications/Save/Done",
"text": "Saved wiki"
},
"$:/language/Notifications/Save/Starting": {
"title": "$:/language/Notifications/Save/Starting",
"text": "Starting to save wiki"
},
"$:/language/Notifications/CopiedToClipboard/Succeeded": {
"title": "$:/language/Notifications/CopiedToClipboard/Succeeded",
"text": "Copied to clipboard!"
},
"$:/language/Notifications/CopiedToClipboard/Failed": {
"title": "$:/language/Notifications/CopiedToClipboard/Failed",
"text": "Failed to copy to clipboard!"
},
"$:/language/Search/DefaultResults/Caption": {
"title": "$:/language/Search/DefaultResults/Caption",
"text": "List"
},
"$:/language/Search/Filter/Caption": {
"title": "$:/language/Search/Filter/Caption",
"text": "Filter"
},
"$:/language/Search/Filter/Hint": {
"title": "$:/language/Search/Filter/Hint",
"text": "Search via a [[filter expression|https://tiddlywiki.com/static/Filters.html]]"
},
"$:/language/Search/Filter/Matches": {
"title": "$:/language/Search/Filter/Matches",
"text": "//<small><<resultCount>> matches</small>//"
},
"$:/language/Search/Matches": {
"title": "$:/language/Search/Matches",
"text": "//<small><<resultCount>> matches</small>//"
},
"$:/language/Search/Matches/All": {
"title": "$:/language/Search/Matches/All",
"text": "All matches:"
},
"$:/language/Search/Matches/Title": {
"title": "$:/language/Search/Matches/Title",
"text": "Title matches:"
},
"$:/language/Search/Search": {
"title": "$:/language/Search/Search",
"text": "Search"
},
"$:/language/Search/Search/TooShort": {
"title": "$:/language/Search/Search/TooShort",
"text": "Search text too short"
},
"$:/language/Search/Shadows/Caption": {
"title": "$:/language/Search/Shadows/Caption",
"text": "Shadows"
},
"$:/language/Search/Shadows/Hint": {
"title": "$:/language/Search/Shadows/Hint",
"text": "Search for shadow tiddlers"
},
"$:/language/Search/Shadows/Matches": {
"title": "$:/language/Search/Shadows/Matches",
"text": "//<small><<resultCount>> matches</small>//"
},
"$:/language/Search/Standard/Caption": {
"title": "$:/language/Search/Standard/Caption",
"text": "Standard"
},
"$:/language/Search/Standard/Hint": {
"title": "$:/language/Search/Standard/Hint",
"text": "Search for standard tiddlers"
},
"$:/language/Search/Standard/Matches": {
"title": "$:/language/Search/Standard/Matches",
"text": "//<small><<resultCount>> matches</small>//"
},
"$:/language/Search/System/Caption": {
"title": "$:/language/Search/System/Caption",
"text": "System"
},
"$:/language/Search/System/Hint": {
"title": "$:/language/Search/System/Hint",
"text": "Search for system tiddlers"
},
"$:/language/Search/System/Matches": {
"title": "$:/language/Search/System/Matches",
"text": "//<small><<resultCount>> matches</small>//"
},
"$:/language/SideBar/All/Caption": {
"title": "$:/language/SideBar/All/Caption",
"text": "All"
},
"$:/language/SideBar/Contents/Caption": {
"title": "$:/language/SideBar/Contents/Caption",
"text": "Contents"
},
"$:/language/SideBar/Drafts/Caption": {
"title": "$:/language/SideBar/Drafts/Caption",
"text": "Drafts"
},
"$:/language/SideBar/Explorer/Caption": {
"title": "$:/language/SideBar/Explorer/Caption",
"text": "Explorer"
},
"$:/language/SideBar/Missing/Caption": {
"title": "$:/language/SideBar/Missing/Caption",
"text": "Missing"
},
"$:/language/SideBar/More/Caption": {
"title": "$:/language/SideBar/More/Caption",
"text": "More"
},
"$:/language/SideBar/Open/Caption": {
"title": "$:/language/SideBar/Open/Caption",
"text": "Open"
},
"$:/language/SideBar/Orphans/Caption": {
"title": "$:/language/SideBar/Orphans/Caption",
"text": "Orphans"
},
"$:/language/SideBar/Recent/Caption": {
"title": "$:/language/SideBar/Recent/Caption",
"text": "Recent"
},
"$:/language/SideBar/Shadows/Caption": {
"title": "$:/language/SideBar/Shadows/Caption",
"text": "Shadows"
},
"$:/language/SideBar/System/Caption": {
"title": "$:/language/SideBar/System/Caption",
"text": "System"
},
"$:/language/SideBar/Tags/Caption": {
"title": "$:/language/SideBar/Tags/Caption",
"text": "Tags"
},
"$:/language/SideBar/Tags/Untagged/Caption": {
"title": "$:/language/SideBar/Tags/Untagged/Caption",
"text": "untagged"
},
"$:/language/SideBar/Tools/Caption": {
"title": "$:/language/SideBar/Tools/Caption",
"text": "Tools"
},
"$:/language/SideBar/Types/Caption": {
"title": "$:/language/SideBar/Types/Caption",
"text": "Types"
},
"$:/SiteSubtitle": {
"title": "$:/SiteSubtitle",
"text": "a non-linear personal web notebook"
},
"$:/SiteTitle": {
"title": "$:/SiteTitle",
"text": "My ~TiddlyWiki"
},
"$:/language/Snippets/ListByTag": {
"title": "$:/language/Snippets/ListByTag",
"tags": "$:/tags/TextEditor/Snippet",
"caption": "List of tiddlers by tag",
"text": "<<list-links \"[tag[task]sort[title]]\">>\n"
},
"$:/language/Snippets/MacroDefinition": {
"title": "$:/language/Snippets/MacroDefinition",
"tags": "$:/tags/TextEditor/Snippet",
"caption": "Macro definition",
"text": "\\define macroName(param1:\"default value\",param2)\nText of the macro\n\\end\n"
},
"$:/language/Snippets/Table4x3": {
"title": "$:/language/Snippets/Table4x3",
"tags": "$:/tags/TextEditor/Snippet",
"caption": "Table with 4 columns by 3 rows",
"text": "|! |!Alpha |!Beta |!Gamma |!Delta |\n|!One | | | | |\n|!Two | | | | |\n|!Three | | | | |\n"
},
"$:/language/Snippets/TableOfContents": {
"title": "$:/language/Snippets/TableOfContents",
"tags": "$:/tags/TextEditor/Snippet",
"caption": "Table of Contents",
"text": "<div class=\"tc-table-of-contents\">\n\n<<toc-selective-expandable 'TableOfContents'>>\n\n</div>"
},
"$:/language/ThemeTweaks/ThemeTweaks": {
"title": "$:/language/ThemeTweaks/ThemeTweaks",
"text": "Theme Tweaks"
},
"$:/language/ThemeTweaks/ThemeTweaks/Hint": {
"title": "$:/language/ThemeTweaks/ThemeTweaks/Hint",
"text": "You can tweak certain aspects of the ''Vanilla'' theme."
},
"$:/language/ThemeTweaks/Options": {
"title": "$:/language/ThemeTweaks/Options",
"text": "Options"
},
"$:/language/ThemeTweaks/Options/SidebarLayout": {
"title": "$:/language/ThemeTweaks/Options/SidebarLayout",
"text": "Sidebar layout"
},
"$:/language/ThemeTweaks/Options/SidebarLayout/Fixed-Fluid": {
"title": "$:/language/ThemeTweaks/Options/SidebarLayout/Fixed-Fluid",
"text": "Fixed story, fluid sidebar"
},
"$:/language/ThemeTweaks/Options/SidebarLayout/Fluid-Fixed": {
"title": "$:/language/ThemeTweaks/Options/SidebarLayout/Fluid-Fixed",
"text": "Fluid story, fixed sidebar"
},
"$:/language/ThemeTweaks/Options/StickyTitles": {
"title": "$:/language/ThemeTweaks/Options/StickyTitles",
"text": "Sticky titles"
},
"$:/language/ThemeTweaks/Options/StickyTitles/Hint": {
"title": "$:/language/ThemeTweaks/Options/StickyTitles/Hint",
"text": "Causes tiddler titles to \"stick\" to the top of the browser window"
},
"$:/language/ThemeTweaks/Options/CodeWrapping": {
"title": "$:/language/ThemeTweaks/Options/CodeWrapping",
"text": "Wrap long lines in code blocks"
},
"$:/language/ThemeTweaks/Settings": {
"title": "$:/language/ThemeTweaks/Settings",
"text": "Settings"
},
"$:/language/ThemeTweaks/Settings/FontFamily": {
"title": "$:/language/ThemeTweaks/Settings/FontFamily",
"text": "Font family"
},
"$:/language/ThemeTweaks/Settings/CodeFontFamily": {
"title": "$:/language/ThemeTweaks/Settings/CodeFontFamily",
"text": "Code font family"
},
"$:/language/ThemeTweaks/Settings/EditorFontFamily": {
"title": "$:/language/ThemeTweaks/Settings/EditorFontFamily",
"text": "Editor font family"
},
"$:/language/ThemeTweaks/Settings/BackgroundImage": {
"title": "$:/language/ThemeTweaks/Settings/BackgroundImage",
"text": "Page background image"
},
"$:/language/ThemeTweaks/Settings/BackgroundImageAttachment": {
"title": "$:/language/ThemeTweaks/Settings/BackgroundImageAttachment",
"text": "Page background image attachment"
},
"$:/language/ThemeTweaks/Settings/BackgroundImageAttachment/Scroll": {
"title": "$:/language/ThemeTweaks/Settings/BackgroundImageAttachment/Scroll",
"text": "Scroll with tiddlers"
},
"$:/language/ThemeTweaks/Settings/BackgroundImageAttachment/Fixed": {
"title": "$:/language/ThemeTweaks/Settings/BackgroundImageAttachment/Fixed",
"text": "Fixed to window"
},
"$:/language/ThemeTweaks/Settings/BackgroundImageSize": {
"title": "$:/language/ThemeTweaks/Settings/BackgroundImageSize",
"text": "Page background image size"
},
"$:/language/ThemeTweaks/Settings/BackgroundImageSize/Auto": {
"title": "$:/language/ThemeTweaks/Settings/BackgroundImageSize/Auto",
"text": "Auto"
},
"$:/language/ThemeTweaks/Settings/BackgroundImageSize/Cover": {
"title": "$:/language/ThemeTweaks/Settings/BackgroundImageSize/Cover",
"text": "Cover"
},
"$:/language/ThemeTweaks/Settings/BackgroundImageSize/Contain": {
"title": "$:/language/ThemeTweaks/Settings/BackgroundImageSize/Contain",
"text": "Contain"
},
"$:/language/ThemeTweaks/Metrics": {
"title": "$:/language/ThemeTweaks/Metrics",
"text": "Sizes"
},
"$:/language/ThemeTweaks/Metrics/FontSize": {
"title": "$:/language/ThemeTweaks/Metrics/FontSize",
"text": "Font size"
},
"$:/language/ThemeTweaks/Metrics/LineHeight": {
"title": "$:/language/ThemeTweaks/Metrics/LineHeight",
"text": "Line height"
},
"$:/language/ThemeTweaks/Metrics/BodyFontSize": {
"title": "$:/language/ThemeTweaks/Metrics/BodyFontSize",
"text": "Font size for tiddler body"
},
"$:/language/ThemeTweaks/Metrics/BodyLineHeight": {
"title": "$:/language/ThemeTweaks/Metrics/BodyLineHeight",
"text": "Line height for tiddler body"
},
"$:/language/ThemeTweaks/Metrics/StoryLeft": {
"title": "$:/language/ThemeTweaks/Metrics/StoryLeft",
"text": "Story left position"
},
"$:/language/ThemeTweaks/Metrics/StoryLeft/Hint": {
"title": "$:/language/ThemeTweaks/Metrics/StoryLeft/Hint",
"text": "how far the left margin of the story river<br>(tiddler area) is from the left of the page"
},
"$:/language/ThemeTweaks/Metrics/StoryTop": {
"title": "$:/language/ThemeTweaks/Metrics/StoryTop",
"text": "Story top position"
},
"$:/language/ThemeTweaks/Metrics/StoryTop/Hint": {
"title": "$:/language/ThemeTweaks/Metrics/StoryTop/Hint",
"text": "how far the top margin of the story river<br>is from the top of the page"
},
"$:/language/ThemeTweaks/Metrics/StoryRight": {
"title": "$:/language/ThemeTweaks/Metrics/StoryRight",
"text": "Story right"
},
"$:/language/ThemeTweaks/Metrics/StoryRight/Hint": {
"title": "$:/language/ThemeTweaks/Metrics/StoryRight/Hint",
"text": "how far the left margin of the sidebar <br>is from the left of the page"
},
"$:/language/ThemeTweaks/Metrics/StoryWidth": {
"title": "$:/language/ThemeTweaks/Metrics/StoryWidth",
"text": "Story width"
},
"$:/language/ThemeTweaks/Metrics/StoryWidth/Hint": {
"title": "$:/language/ThemeTweaks/Metrics/StoryWidth/Hint",
"text": "the overall width of the story river"
},
"$:/language/ThemeTweaks/Metrics/TiddlerWidth": {
"title": "$:/language/ThemeTweaks/Metrics/TiddlerWidth",
"text": "Tiddler width"
},
"$:/language/ThemeTweaks/Metrics/TiddlerWidth/Hint": {
"title": "$:/language/ThemeTweaks/Metrics/TiddlerWidth/Hint",
"text": "within the story river"
},
"$:/language/ThemeTweaks/Metrics/SidebarBreakpoint": {
"title": "$:/language/ThemeTweaks/Metrics/SidebarBreakpoint",
"text": "Sidebar breakpoint"
},
"$:/language/ThemeTweaks/Metrics/SidebarBreakpoint/Hint": {
"title": "$:/language/ThemeTweaks/Metrics/SidebarBreakpoint/Hint",
"text": "the minimum page width at which the story<br>river and sidebar will appear side by side"
},
"$:/language/ThemeTweaks/Metrics/SidebarWidth": {
"title": "$:/language/ThemeTweaks/Metrics/SidebarWidth",
"text": "Sidebar width"
},
"$:/language/ThemeTweaks/Metrics/SidebarWidth/Hint": {
"title": "$:/language/ThemeTweaks/Metrics/SidebarWidth/Hint",
"text": "the width of the sidebar in fluid-fixed layout"
},
"$:/language/TiddlerInfo/Advanced/Caption": {
"title": "$:/language/TiddlerInfo/Advanced/Caption",
"text": "Advanced"
},
"$:/language/TiddlerInfo/Advanced/PluginInfo/Empty/Hint": {
"title": "$:/language/TiddlerInfo/Advanced/PluginInfo/Empty/Hint",
"text": "none"
},
"$:/language/TiddlerInfo/Advanced/PluginInfo/Heading": {
"title": "$:/language/TiddlerInfo/Advanced/PluginInfo/Heading",
"text": "Plugin Details"
},
"$:/language/TiddlerInfo/Advanced/PluginInfo/Hint": {
"title": "$:/language/TiddlerInfo/Advanced/PluginInfo/Hint",
"text": "This plugin contains the following shadow tiddlers:"
},
"$:/language/TiddlerInfo/Advanced/ShadowInfo/Heading": {
"title": "$:/language/TiddlerInfo/Advanced/ShadowInfo/Heading",
"text": "Shadow Status"
},
"$:/language/TiddlerInfo/Advanced/ShadowInfo/NotShadow/Hint": {
"title": "$:/language/TiddlerInfo/Advanced/ShadowInfo/NotShadow/Hint",
"text": "The tiddler <$link to=<<infoTiddler>>><$text text=<<infoTiddler>>/></$link> is not a shadow tiddler"
},
"$:/language/TiddlerInfo/Advanced/ShadowInfo/Shadow/Hint": {
"title": "$:/language/TiddlerInfo/Advanced/ShadowInfo/Shadow/Hint",
"text": "The tiddler <$link to=<<infoTiddler>>><$text text=<<infoTiddler>>/></$link> is a shadow tiddler"
},
"$:/language/TiddlerInfo/Advanced/ShadowInfo/Shadow/Source": {
"title": "$:/language/TiddlerInfo/Advanced/ShadowInfo/Shadow/Source",
"text": "It is defined in the plugin <$link to=<<pluginTiddler>>><$text text=<<pluginTiddler>>/></$link>"
},
"$:/language/TiddlerInfo/Advanced/ShadowInfo/OverriddenShadow/Hint": {
"title": "$:/language/TiddlerInfo/Advanced/ShadowInfo/OverriddenShadow/Hint",
"text": "It is overridden by an ordinary tiddler"
},
"$:/language/TiddlerInfo/Fields/Caption": {
"title": "$:/language/TiddlerInfo/Fields/Caption",
"text": "Fields"
},
"$:/language/TiddlerInfo/List/Caption": {
"title": "$:/language/TiddlerInfo/List/Caption",
"text": "List"
},
"$:/language/TiddlerInfo/List/Empty": {
"title": "$:/language/TiddlerInfo/List/Empty",
"text": "This tiddler does not have a list"
},
"$:/language/TiddlerInfo/Listed/Caption": {
"title": "$:/language/TiddlerInfo/Listed/Caption",
"text": "Listed"
},
"$:/language/TiddlerInfo/Listed/Empty": {
"title": "$:/language/TiddlerInfo/Listed/Empty",
"text": "This tiddler is not listed by any others"
},
"$:/language/TiddlerInfo/References/Caption": {
"title": "$:/language/TiddlerInfo/References/Caption",
"text": "References"
},
"$:/language/TiddlerInfo/References/Empty": {
"title": "$:/language/TiddlerInfo/References/Empty",
"text": "No tiddlers link to this one"
},
"$:/language/TiddlerInfo/Tagging/Caption": {
"title": "$:/language/TiddlerInfo/Tagging/Caption",
"text": "Tagging"
},
"$:/language/TiddlerInfo/Tagging/Empty": {
"title": "$:/language/TiddlerInfo/Tagging/Empty",
"text": "No tiddlers are tagged with this one"
},
"$:/language/TiddlerInfo/Tools/Caption": {
"title": "$:/language/TiddlerInfo/Tools/Caption",
"text": "Tools"
},
"$:/language/Docs/Types/application/javascript": {
"title": "$:/language/Docs/Types/application/javascript",
"description": "JavaScript code",
"name": "application/javascript",
"group": "Developer",
"group-sort": "2"
},
"$:/language/Docs/Types/application/json": {
"title": "$:/language/Docs/Types/application/json",
"description": "JSON data",
"name": "application/json",
"group": "Developer",
"group-sort": "2"
},
"$:/language/Docs/Types/application/x-tiddler-dictionary": {
"title": "$:/language/Docs/Types/application/x-tiddler-dictionary",
"description": "Data dictionary",
"name": "application/x-tiddler-dictionary",
"group": "Developer",
"group-sort": "2"
},
"$:/language/Docs/Types/image/gif": {
"title": "$:/language/Docs/Types/image/gif",
"description": "GIF image",
"name": "image/gif",
"group": "Image",
"group-sort": "1"
},
"$:/language/Docs/Types/image/jpeg": {
"title": "$:/language/Docs/Types/image/jpeg",
"description": "JPEG image",
"name": "image/jpeg",
"group": "Image",
"group-sort": "1"
},
"$:/language/Docs/Types/image/png": {
"title": "$:/language/Docs/Types/image/png",
"description": "PNG image",
"name": "image/png",
"group": "Image",
"group-sort": "1"
},
"$:/language/Docs/Types/image/svg+xml": {
"title": "$:/language/Docs/Types/image/svg+xml",
"description": "Structured Vector Graphics image",
"name": "image/svg+xml",
"group": "Image",
"group-sort": "1"
},
"$:/language/Docs/Types/image/x-icon": {
"title": "$:/language/Docs/Types/image/x-icon",
"description": "ICO format icon file",
"name": "image/x-icon",
"group": "Image",
"group-sort": "1"
},
"$:/language/Docs/Types/text/css": {
"title": "$:/language/Docs/Types/text/css",
"description": "Static stylesheet",
"name": "text/css",
"group": "Developer",
"group-sort": "2"
},
"$:/language/Docs/Types/text/html": {
"title": "$:/language/Docs/Types/text/html",
"description": "HTML markup",
"name": "text/html",
"group": "Text",
"group-sort": "0"
},
"$:/language/Docs/Types/text/plain": {
"title": "$:/language/Docs/Types/text/plain",
"description": "Plain text",
"name": "text/plain",
"group": "Text",
"group-sort": "0"
},
"$:/language/Docs/Types/text/vnd.tiddlywiki": {
"title": "$:/language/Docs/Types/text/vnd.tiddlywiki",
"description": "TiddlyWiki 5",
"name": "text/vnd.tiddlywiki",
"group": "Text",
"group-sort": "0"
},
"$:/language/Docs/Types/text/x-tiddlywiki": {
"title": "$:/language/Docs/Types/text/x-tiddlywiki",
"description": "TiddlyWiki Classic",
"name": "text/x-tiddlywiki",
"group": "Text",
"group-sort": "0"
},
"$:/languages/en-GB/icon": {
"title": "$:/languages/en-GB/icon",
"type": "image/svg+xml",
"text": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 60 30\" width=\"1200\" height=\"600\">\n<clipPath id=\"t\">\n\t<path d=\"M30,15 h30 v15 z v15 h-30 z h-30 v-15 z v-15 h30 z\"/>\n</clipPath>\n<path d=\"M0,0 v30 h60 v-30 z\" fill=\"#00247d\"/>\n<path d=\"M0,0 L60,30 M60,0 L0,30\" stroke=\"#fff\" stroke-width=\"6\"/>\n<path d=\"M0,0 L60,30 M60,0 L0,30\" clip-path=\"url(#t)\" stroke=\"#cf142b\" stroke-width=\"4\"/>\n<path d=\"M30,0 v30 M0,15 h60\" stroke=\"#fff\" stroke-width=\"10\"/>\n<path d=\"M30,0 v30 M0,15 h60\" stroke=\"#cf142b\" stroke-width=\"6\"/>\n</svg>\n"
},
"$:/languages/en-GB": {
"title": "$:/languages/en-GB",
"name": "en-GB",
"description": "English (British)",
"author": "JeremyRuston",
"core-version": ">=5.0.0\"",
"text": "Stub pseudo-plugin for the default language"
},
"$:/core/modules/commander.js": {
"title": "$:/core/modules/commander.js",
"text": "/*\\\ntitle: $:/core/modules/commander.js\ntype: application/javascript\nmodule-type: global\n\nThe $tw.Commander class is a command interpreter\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nParse a sequence of commands\n\tcommandTokens: an array of command string tokens\n\twiki: reference to the wiki store object\n\tstreams: {output:, error:}, each of which has a write(string) method\n\tcallback: a callback invoked as callback(err) where err is null if there was no error\n*/\nvar Commander = function(commandTokens,callback,wiki,streams) {\n\tvar path = require(\"path\");\n\tthis.commandTokens = commandTokens;\n\tthis.nextToken = 0;\n\tthis.callback = callback;\n\tthis.wiki = wiki;\n\tthis.streams = streams;\n\tthis.outputPath = path.resolve($tw.boot.wikiPath,$tw.config.wikiOutputSubDir);\n};\n\n/*\nLog a string if verbose flag is set\n*/\nCommander.prototype.log = function(str) {\n\tif(this.verbose) {\n\t\tthis.streams.output.write(str + \"\\n\");\n\t}\n};\n\n/*\nWrite a string if verbose flag is set\n*/\nCommander.prototype.write = function(str) {\n\tif(this.verbose) {\n\t\tthis.streams.output.write(str);\n\t}\n};\n\n/*\nAdd a string of tokens to the command queue\n*/\nCommander.prototype.addCommandTokens = function(commandTokens) {\n\tvar params = commandTokens.slice(0);\n\tparams.unshift(0);\n\tparams.unshift(this.nextToken);\n\tArray.prototype.splice.apply(this.commandTokens,params);\n};\n\n/*\nExecute the sequence of commands and invoke a callback on completion\n*/\nCommander.prototype.execute = function() {\n\tthis.executeNextCommand();\n};\n\n/*\nExecute the next command in the sequence\n*/\nCommander.prototype.executeNextCommand = function() {\n\tvar self = this;\n\t// Invoke the callback if there are no more commands\n\tif(this.nextToken >= this.commandTokens.length) {\n\t\tthis.callback(null);\n\t} else {\n\t\t// Get and check the command token\n\t\tvar commandName = this.commandTokens[this.nextToken++];\n\t\tif(commandName.substr(0,2) !== \"--\") {\n\t\t\tthis.callback(\"Missing command: \" + commandName);\n\t\t} else {\n\t\t\tcommandName = commandName.substr(2); // Trim off the --\n\t\t\t// Accumulate the parameters to the command\n\t\t\tvar params = [];\n\t\t\twhile(this.nextToken < this.commandTokens.length && \n\t\t\t\tthis.commandTokens[this.nextToken].substr(0,2) !== \"--\") {\n\t\t\t\tparams.push(this.commandTokens[this.nextToken++]);\n\t\t\t}\n\t\t\t// Get the command info\n\t\t\tvar command = $tw.commands[commandName],\n\t\t\t\tc,err;\n\t\t\tif(!command) {\n\t\t\t\tthis.callback(\"Unknown command: \" + commandName);\n\t\t\t} else {\n\t\t\t\tif(this.verbose) {\n\t\t\t\t\tthis.streams.output.write(\"Executing command: \" + commandName + \" \" + params.join(\" \") + \"\\n\");\n\t\t\t\t}\n\t\t\t\t// Parse named parameters if required\n\t\t\t\tif(command.info.namedParameterMode) {\n\t\t\t\t\tparams = this.extractNamedParameters(params,command.info.mandatoryParameters);\n\t\t\t\t\tif(typeof params === \"string\") {\n\t\t\t\t\t\treturn this.callback(params);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif(command.info.synchronous) {\n\t\t\t\t\t// Synchronous command\n\t\t\t\t\tc = new command.Command(params,this);\n\t\t\t\t\terr = c.execute();\n\t\t\t\t\tif(err) {\n\t\t\t\t\t\tthis.callback(err);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.executeNextCommand();\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Asynchronous command\n\t\t\t\t\tc = new command.Command(params,this,function(err) {\n\t\t\t\t\t\tif(err) {\n\t\t\t\t\t\t\tself.callback(err);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tself.executeNextCommand();\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\terr = c.execute();\n\t\t\t\t\tif(err) {\n\t\t\t\t\t\tthis.callback(err);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n};\n\n/*\nGiven an array of parameter strings `params` in name:value format, and an array of mandatory parameter names in `mandatoryParameters`, returns a hashmap of values or a string if error\n*/\nCommander.prototype.extractNamedParameters = function(params,mandatoryParameters) {\n\tmandatoryParameters = mandatoryParameters || [];\n\tvar errors = [],\n\t\tparamsByName = Object.create(null);\n\t// Extract the parameters\n\t$tw.utils.each(params,function(param) {\n\t\tvar index = param.indexOf(\"=\");\n\t\tif(index < 1) {\n\t\t\terrors.push(\"malformed named parameter: '\" + param + \"'\");\n\t\t}\n\t\tparamsByName[param.slice(0,index)] = $tw.utils.trim(param.slice(index+1));\n\t});\n\t// Check the mandatory parameters are present\n\t$tw.utils.each(mandatoryParameters,function(mandatoryParameter) {\n\t\tif(!$tw.utils.hop(paramsByName,mandatoryParameter)) {\n\t\t\terrors.push(\"missing mandatory parameter: '\" + mandatoryParameter + \"'\");\n\t\t}\n\t});\n\t// Return any errors\n\tif(errors.length > 0) {\n\t\treturn errors.join(\" and\\n\");\n\t} else {\n\t\treturn paramsByName;\t\t\n\t}\n};\n\nCommander.initCommands = function(moduleType) {\n\tmoduleType = moduleType || \"command\";\n\t$tw.commands = {};\n\t$tw.modules.forEachModuleOfType(moduleType,function(title,module) {\n\t\tvar c = $tw.commands[module.info.name] = {};\n\t\t// Add the methods defined by the module\n\t\tfor(var f in module) {\n\t\t\tif($tw.utils.hop(module,f)) {\n\t\t\t\tc[f] = module[f];\n\t\t\t}\n\t\t}\n\t});\n};\n\nexports.Commander = Commander;\n\n})();\n",
"type": "application/javascript",
"module-type": "global"
},
"$:/core/modules/commands/build.js": {
"title": "$:/core/modules/commands/build.js",
"text": "/*\\\ntitle: $:/core/modules/commands/build.js\ntype: application/javascript\nmodule-type: command\n\nCommand to build a build target\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"build\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander) {\n\tthis.params = params;\n\tthis.commander = commander;\n};\n\nCommand.prototype.execute = function() {\n\t// Get the build targets defined in the wiki\n\tvar buildTargets = $tw.boot.wikiInfo.build;\n\tif(!buildTargets) {\n\t\treturn \"No build targets defined\";\n\t}\n\t// Loop through each of the specified targets\n\tvar targets;\n\tif(this.params.length > 0) {\n\t\ttargets = this.params;\n\t} else {\n\t\ttargets = Object.keys(buildTargets);\n\t}\n\tfor(var targetIndex=0; targetIndex<targets.length; targetIndex++) {\n\t\tvar target = targets[targetIndex],\n\t\t\tcommands = buildTargets[target];\n\t\tif(!commands) {\n\t\t\treturn \"Build target '\" + target + \"' not found\";\n\t\t}\n\t\t// Add the commands to the queue\n\t\tthis.commander.addCommandTokens(commands);\n\t}\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/commands/clearpassword.js": {
"title": "$:/core/modules/commands/clearpassword.js",
"text": "/*\\\ntitle: $:/core/modules/commands/clearpassword.js\ntype: application/javascript\nmodule-type: command\n\nClear password for crypto operations\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"clearpassword\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\t$tw.crypto.setPassword(null);\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/commands/editions.js": {
"title": "$:/core/modules/commands/editions.js",
"text": "/*\\\ntitle: $:/core/modules/commands/editions.js\ntype: application/javascript\nmodule-type: command\n\nCommand to list the available editions\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"editions\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander) {\n\tthis.params = params;\n\tthis.commander = commander;\n};\n\nCommand.prototype.execute = function() {\n\tvar self = this;\n\t// Output the list\n\tthis.commander.streams.output.write(\"Available editions:\\n\\n\");\n\tvar editionInfo = $tw.utils.getEditionInfo();\n\t$tw.utils.each(editionInfo,function(info,name) {\n\t\tself.commander.streams.output.write(\" \" + name + \": \" + info.description + \"\\n\");\n\t});\n\tthis.commander.streams.output.write(\"\\n\");\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/commands/fetch.js": {
"title": "$:/core/modules/commands/fetch.js",
"text": "/*\\\ntitle: $:/core/modules/commands/fetch.js\ntype: application/javascript\nmodule-type: command\n\nCommands to fetch external tiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"fetch\",\n\tsynchronous: false\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(this.params.length < 2) {\n\t\treturn \"Missing subcommand and url\";\n\t}\n\tswitch(this.params[0]) {\n\t\tcase \"raw-file\":\n\t\t\treturn this.fetchFiles({\n\t\t\t\traw: true,\n\t\t\t\turl: this.params[1],\n\t\t\t\ttransformFilter: this.params[2] || \"\",\n\t\t\t\tcallback: this.callback\n\t\t\t});\n\t\t\tbreak;\n\t\tcase \"file\":\n\t\t\treturn this.fetchFiles({\n\t\t\t\turl: this.params[1],\n\t\t\t\timportFilter: this.params[2],\n\t\t\t\ttransformFilter: this.params[3] || \"\",\n\t\t\t\tcallback: this.callback\n\t\t\t});\n\t\t\tbreak;\n\t\tcase \"raw-files\":\n\t\t\treturn this.fetchFiles({\n\t\t\t\traw: true,\n\t\t\t\turlFilter: this.params[1],\n\t\t\t\ttransformFilter: this.params[2] || \"\",\n\t\t\t\tcallback: this.callback\n\t\t\t});\n\t\t\tbreak;\n\t\tcase \"files\":\n\t\t\treturn this.fetchFiles({\n\t\t\t\turlFilter: this.params[1],\n\t\t\t\timportFilter: this.params[2],\n\t\t\t\ttransformFilter: this.params[3] || \"\",\n\t\t\t\tcallback: this.callback\n\t\t\t});\n\t\t\tbreak;\n\t}\n\treturn null;\n};\n\nCommand.prototype.fetchFiles = function(options) {\n\tvar self = this;\n\t// Get the list of URLs\n\tvar urls;\n\tif(options.url) {\n\t\turls = [options.url]\n\t} else if(options.urlFilter) {\n\t\turls = $tw.wiki.filterTiddlers(options.urlFilter);\n\t} else {\n\t\treturn \"Missing URL\";\n\t}\n\t// Process each URL in turn\n\tvar next = 0;\n\tvar getNextFile = function(err) {\n\t\tif(err) {\n\t\t\treturn options.callback(err);\n\t\t}\n\t\tif(next < urls.length) {\n\t\t\tself.fetchFile(urls[next++],options,getNextFile);\n\t\t} else {\n\t\t\toptions.callback(null);\n\t\t}\n\t};\n\tgetNextFile(null);\n\t// Success\n\treturn null;\n};\n\nCommand.prototype.fetchFile = function(url,options,callback,redirectCount) {\n\tif(redirectCount > 10) {\n\t\treturn callback(\"Error too many redirects retrieving \" + url);\n\t}\n\tvar self = this,\n\t\tlib = url.substr(0,8) === \"https://\" ? require(\"https\") : require(\"http\");\n\tlib.get(url).on(\"response\",function(response) {\n\t var type = (response.headers[\"content-type\"] || \"\").split(\";\")[0],\n\t \tdata = [];\n\t self.commander.write(\"Reading \" + url + \": \");\n\t response.on(\"data\",function(chunk) {\n\t data.push(chunk);\n\t self.commander.write(\".\");\n\t });\n\t response.on(\"end\",function() {\n\t self.commander.write(\"\\n\");\n\t if(response.statusCode === 200) {\n\t\t self.processBody(Buffer.concat(data),type,options,url);\n\t\t callback(null);\n\t } else {\n\t \tif(response.statusCode === 302 || response.statusCode === 303 || response.statusCode === 307) {\n\t \t\treturn self.fetchFile(response.headers.location,options,callback,redirectCount + 1);\n\t \t} else {\n\t\t \treturn callback(\"Error \" + response.statusCode + \" retrieving \" + url)\t \t\t\n\t \t}\n\t }\n\t \t});\n\t \tresponse.on(\"error\",function(e) {\n\t\t\tconsole.log(\"Error on GET request: \" + e);\n\t\t\tcallback(e);\n\t \t});\n\t});\n\treturn null;\n};\n\nCommand.prototype.processBody = function(body,type,options,url) {\n\tvar self = this;\n\t// Collect the tiddlers in a wiki\n\tvar incomingWiki = new $tw.Wiki();\n\tif(options.raw) {\n\t\tvar typeInfo = type ? $tw.config.contentTypeInfo[type] : null,\n\t\t\tencoding = typeInfo ? typeInfo.encoding : \"utf8\";\n\t\tincomingWiki.addTiddler(new $tw.Tiddler({\n\t\t\ttitle: url,\n\t\t\ttype: type,\n\t\t\ttext: body.toString(encoding)\n\t\t}));\n\t} else {\n\t\t// Deserialise the file to extract the tiddlers\n\t\tvar tiddlers = this.commander.wiki.deserializeTiddlers(type || \"text/html\",body.toString(\"utf8\"),{});\n\t\t$tw.utils.each(tiddlers,function(tiddler) {\n\t\t\tincomingWiki.addTiddler(new $tw.Tiddler(tiddler));\n\t\t});\n\t}\n\t// Filter the tiddlers to select the ones we want\n\tvar filteredTitles = incomingWiki.filterTiddlers(options.importFilter || \"[all[tiddlers]]\");\n\t// Import the selected tiddlers\n\tvar count = 0;\n\tincomingWiki.each(function(tiddler,title) {\n\t\tif(filteredTitles.indexOf(title) !== -1) {\n\t\t\tvar newTiddler;\n\t\t\tif(options.transformFilter) {\n\t\t\t\tvar transformedTitle = (incomingWiki.filterTiddlers(options.transformFilter,null,self.commander.wiki.makeTiddlerIterator([title])) || [\"\"])[0];\n\t\t\t\tif(transformedTitle) {\n\t\t\t\t\tself.commander.log(\"Importing \" + title + \" as \" + transformedTitle)\n\t\t\t\t\tnewTiddler = new $tw.Tiddler(tiddler,{title: transformedTitle});\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tself.commander.log(\"Importing \" + title)\n\t\t\t\tnewTiddler = tiddler;\n\t\t\t}\n\t\t\tself.commander.wiki.importTiddler(newTiddler);\n\t\t\tcount++;\n\t\t}\n\t});\n\tself.commander.log(\"Imported \" + count + \" tiddlers\")\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/commands/help.js": {
"title": "$:/core/modules/commands/help.js",
"text": "/*\\\ntitle: $:/core/modules/commands/help.js\ntype: application/javascript\nmodule-type: command\n\nHelp command\n\n\\*/\n(function(){\n\n/*jshint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"help\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander) {\n\tthis.params = params;\n\tthis.commander = commander;\n};\n\nCommand.prototype.execute = function() {\n\tvar subhelp = this.params[0] || \"default\",\n\t\thelpBase = \"$:/language/Help/\",\n\t\ttext;\n\tif(!this.commander.wiki.getTiddler(helpBase + subhelp)) {\n\t\tsubhelp = \"notfound\";\n\t}\n\t// Wikify the help as formatted text (ie block elements generate newlines)\n\ttext = this.commander.wiki.renderTiddler(\"text/plain-formatted\",helpBase + subhelp);\n\t// Remove any leading linebreaks\n\ttext = text.replace(/^(\\r?\\n)*/g,\"\");\n\tthis.commander.streams.output.write(text);\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/commands/import.js": {
"title": "$:/core/modules/commands/import.js",
"text": "/*\\\ntitle: $:/core/modules/commands/import.js\ntype: application/javascript\nmodule-type: command\n\nCommand to import tiddlers from a file\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"import\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tvar self = this,\n\t\tfs = require(\"fs\"),\n\t\tpath = require(\"path\");\n\tif(this.params.length < 2) {\n\t\treturn \"Missing parameters\";\n\t}\n\tvar filename = self.params[0],\n\t\tdeserializer = self.params[1],\n\t\ttitle = self.params[2] || filename,\n\t\tencoding = self.params[3] || \"utf8\",\n\t\ttext = fs.readFileSync(filename,encoding),\n\t\ttiddlers = this.commander.wiki.deserializeTiddlers(null,text,{title: title},{deserializer: deserializer});\n\t$tw.utils.each(tiddlers,function(tiddler) {\n\t\tself.commander.wiki.importTiddler(new $tw.Tiddler(tiddler));\n\t});\n\tthis.commander.log(tiddlers.length + \" tiddler(s) imported\");\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/commands/init.js": {
"title": "$:/core/modules/commands/init.js",
"text": "/*\\\ntitle: $:/core/modules/commands/init.js\ntype: application/javascript\nmodule-type: command\n\nCommand to initialise an empty wiki folder\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"init\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander) {\n\tthis.params = params;\n\tthis.commander = commander;\n};\n\nCommand.prototype.execute = function() {\n\tvar fs = require(\"fs\"),\n\t\tpath = require(\"path\");\n\t// Check that we don't already have a valid wiki folder\n\tif($tw.boot.wikiTiddlersPath || ($tw.utils.isDirectory($tw.boot.wikiPath) && !$tw.utils.isDirectoryEmpty($tw.boot.wikiPath))) {\n\t\treturn \"Wiki folder is not empty\";\n\t}\n\t// Loop through each of the specified editions\n\tvar editions = this.params.length > 0 ? this.params : [\"empty\"];\n\tfor(var editionIndex=0; editionIndex<editions.length; editionIndex++) {\n\t\tvar editionName = editions[editionIndex];\n\t\t// Check the edition exists\n\t\tvar editionPath = $tw.findLibraryItem(editionName,$tw.getLibraryItemSearchPaths($tw.config.editionsPath,$tw.config.editionsEnvVar));\n\t\tif(!$tw.utils.isDirectory(editionPath)) {\n\t\t\treturn \"Edition '\" + editionName + \"' not found\";\n\t\t}\n\t\t// Copy the edition content\n\t\tvar err = $tw.utils.copyDirectory(editionPath,$tw.boot.wikiPath);\n\t\tif(!err) {\n\t\t\tthis.commander.streams.output.write(\"Copied edition '\" + editionName + \"' to \" + $tw.boot.wikiPath + \"\\n\");\n\t\t} else {\n\t\t\treturn err;\n\t\t}\n\t}\n\t// Tweak the tiddlywiki.info to remove any included wikis\n\tvar packagePath = $tw.boot.wikiPath + \"/tiddlywiki.info\",\n\t\tpackageJson = JSON.parse(fs.readFileSync(packagePath));\n\tdelete packageJson.includeWikis;\n\tfs.writeFileSync(packagePath,JSON.stringify(packageJson,null,$tw.config.preferences.jsonSpaces));\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/commands/listen.js": {
"title": "$:/core/modules/commands/listen.js",
"text": "/*\\\ntitle: $:/core/modules/commands/listen.js\ntype: application/javascript\nmodule-type: command\n\nListen for HTTP requests and serve tiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Server = require(\"$:/core/modules/server/server.js\").Server;\n\nexports.info = {\n\tname: \"listen\",\n\tsynchronous: true,\n\tnamedParameterMode: true,\n\tmandatoryParameters: [],\n};\n\nvar Command = function(params,commander,callback) {\n\tvar self = this;\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tvar self = this;\n\tif(!$tw.boot.wikiTiddlersPath) {\n\t\t$tw.utils.warning(\"Warning: Wiki folder '\" + $tw.boot.wikiPath + \"' does not exist or is missing a tiddlywiki.info file\");\n\t}\n\t// Set up server\n\tthis.server = new Server({\n\t\twiki: this.commander.wiki,\n\t\tvariables: self.params\n\t});\n\tvar nodeServer = this.server.listen();\n\t$tw.hooks.invokeHook(\"th-server-command-post-start\",this.server,nodeServer,\"tiddlywiki\");\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/commands/load.js": {
"title": "$:/core/modules/commands/load.js",
"text": "/*\\\ntitle: $:/core/modules/commands/load.js\ntype: application/javascript\nmodule-type: command\n\nCommand to load tiddlers from a file or directory\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"load\",\n\tsynchronous: false\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tvar self = this,\n\t\tfs = require(\"fs\"),\n\t\tpath = require(\"path\");\n\tif(this.params.length < 1) {\n\t\treturn \"Missing filename\";\n\t}\n\tvar tiddlers = $tw.loadTiddlersFromPath(self.params[0]),\n\t\tcount = 0;\n\t$tw.utils.each(tiddlers,function(tiddlerInfo) {\n\t\t$tw.utils.each(tiddlerInfo.tiddlers,function(tiddler) {\n\t\t\tself.commander.wiki.importTiddler(new $tw.Tiddler(tiddler));\n\t\t\tcount++;\n\t\t});\n\t});\n\tif(!count) {\n\t\tself.callback(\"No tiddlers found in file \\\"\" + self.params[0] + \"\\\"\");\n\t} else {\n\t\tself.callback(null);\n\t}\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/commands/makelibrary.js": {
"title": "$:/core/modules/commands/makelibrary.js",
"text": "/*\\\ntitle: $:/core/modules/commands/makelibrary.js\ntype: application/javascript\nmodule-type: command\n\nCommand to pack all of the plugins in the library into a plugin tiddler of type \"library\"\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"makelibrary\",\n\tsynchronous: true\n};\n\nvar UPGRADE_LIBRARY_TITLE = \"$:/UpgradeLibrary\";\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tvar wiki = this.commander.wiki,\n\t\tfs = require(\"fs\"),\n\t\tpath = require(\"path\"),\n\t\tupgradeLibraryTitle = this.params[0] || UPGRADE_LIBRARY_TITLE,\n\t\ttiddlers = {};\n\t// Collect up the library plugins\n\tvar collectPlugins = function(folder) {\n\t\t\tvar pluginFolders = fs.readdirSync(folder);\n\t\t\tfor(var p=0; p<pluginFolders.length; p++) {\n\t\t\t\tif(!$tw.boot.excludeRegExp.test(pluginFolders[p])) {\n\t\t\t\t\tpluginFields = $tw.loadPluginFolder(path.resolve(folder,\"./\" + pluginFolders[p]));\n\t\t\t\t\tif(pluginFields && pluginFields.title) {\n\t\t\t\t\t\ttiddlers[pluginFields.title] = pluginFields;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tcollectPublisherPlugins = function(folder) {\n\t\t\tvar publisherFolders = fs.readdirSync(folder);\n\t\t\tfor(var t=0; t<publisherFolders.length; t++) {\n\t\t\t\tif(!$tw.boot.excludeRegExp.test(publisherFolders[t])) {\n\t\t\t\t\tcollectPlugins(path.resolve(folder,\"./\" + publisherFolders[t]));\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\tcollectPublisherPlugins(path.resolve($tw.boot.corePath,$tw.config.pluginsPath));\n\tcollectPublisherPlugins(path.resolve($tw.boot.corePath,$tw.config.themesPath));\n\tcollectPlugins(path.resolve($tw.boot.corePath,$tw.config.languagesPath));\n\t// Save the upgrade library tiddler\n\tvar pluginFields = {\n\t\ttitle: upgradeLibraryTitle,\n\t\ttype: \"application/json\",\n\t\t\"plugin-type\": \"library\",\n\t\t\"text\": JSON.stringify({tiddlers: tiddlers},null,$tw.config.preferences.jsonSpaces)\n\t};\n\twiki.addTiddler(new $tw.Tiddler(pluginFields));\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/commands/output.js": {
"title": "$:/core/modules/commands/output.js",
"text": "/*\\\ntitle: $:/core/modules/commands/output.js\ntype: application/javascript\nmodule-type: command\n\nCommand to set the default output location (defaults to current working directory)\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"output\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tvar fs = require(\"fs\"),\n\t\tpath = require(\"path\");\n\tif(this.params.length < 1) {\n\t\treturn \"Missing output path\";\n\t}\n\tthis.commander.outputPath = path.resolve(process.cwd(),this.params[0]);\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/commands/password.js": {
"title": "$:/core/modules/commands/password.js",
"text": "/*\\\ntitle: $:/core/modules/commands/password.js\ntype: application/javascript\nmodule-type: command\n\nSave password for crypto operations\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"password\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(this.params.length < 1) {\n\t\treturn \"Missing password\";\n\t}\n\t$tw.crypto.setPassword(this.params[0]);\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/commands/render.js": {
"title": "$:/core/modules/commands/render.js",
"text": "/*\\\ntitle: $:/core/modules/commands/render.js\ntype: application/javascript\nmodule-type: command\n\nRender individual tiddlers and save the results to the specified files\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar widget = require(\"$:/core/modules/widgets/widget.js\");\n\nexports.info = {\n\tname: \"render\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(this.params.length < 1) {\n\t\treturn \"Missing tiddler filter\";\n\t}\n\tvar self = this,\n\t\tfs = require(\"fs\"),\n\t\tpath = require(\"path\"),\n\t\twiki = this.commander.wiki,\n\t\ttiddlerFilter = this.params[0],\n\t\tfilenameFilter = this.params[1] || \"[is[tiddler]addsuffix[.html]]\",\n\t\ttype = this.params[2] || \"text/html\",\n\t\ttemplate = this.params[3],\n\t\tvarName = this.params[4],\n\t\tvarValue = this.params[5],\n\t\ttiddlers = wiki.filterTiddlers(tiddlerFilter);\n\t$tw.utils.each(tiddlers,function(title) {\n\t\tvar parser = wiki.parseTiddler(template || title),\n\t\t\tvariables = {currentTiddler: title};\n\t\tif(varName) {\n\t\t\tvariables[varName] = varValue || \"\";\n\t\t}\n\t\tvar widgetNode = wiki.makeWidget(parser,{variables: variables}),\n\t\t\tcontainer = $tw.fakeDocument.createElement(\"div\");\n\t\twidgetNode.render(container,null);\n\t\tvar text = type === \"text/html\" ? container.innerHTML : container.textContent,\n\t\t\tfilepath = path.resolve(self.commander.outputPath,wiki.filterTiddlers(filenameFilter,$tw.rootWidget,wiki.makeTiddlerIterator([title]))[0]);\n\t\tif(self.commander.verbose) {\n\t\t\tconsole.log(\"Rendering \\\"\" + title + \"\\\" to \\\"\" + filepath + \"\\\"\");\n\t\t}\n\t\t$tw.utils.createFileDirectories(filepath);\n\t\tfs.writeFileSync(filepath,text,\"utf8\");\n\t});\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/commands/rendertiddler.js": {
"title": "$:/core/modules/commands/rendertiddler.js",
"text": "/*\\\ntitle: $:/core/modules/commands/rendertiddler.js\ntype: application/javascript\nmodule-type: command\n\nCommand to render a tiddler and save it to a file\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"rendertiddler\",\n\tsynchronous: false\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(this.params.length < 2) {\n\t\treturn \"Missing filename\";\n\t}\n\tvar self = this,\n\t\tfs = require(\"fs\"),\n\t\tpath = require(\"path\"),\n\t\ttitle = this.params[0],\n\t\tfilename = path.resolve(this.commander.outputPath,this.params[1]),\n\t\ttype = this.params[2] || \"text/html\",\n\t\ttemplate = this.params[3],\n\t\tname = this.params[4],\n\t\tvalue = this.params[5],\n\t\tvariables = {};\n\t$tw.utils.createFileDirectories(filename);\n\tif(template) {\n\t\tvariables.currentTiddler = title;\n\t\ttitle = template;\n\t}\n\tif(name && value) {\n\t\tvariables[name] = value;\n\t}\n\tfs.writeFile(filename,this.commander.wiki.renderTiddler(type,title,{variables: variables}),\"utf8\",function(err) {\n\t\tself.callback(err);\n\t});\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/commands/rendertiddlers.js": {
"title": "$:/core/modules/commands/rendertiddlers.js",
"text": "/*\\\ntitle: $:/core/modules/commands/rendertiddlers.js\ntype: application/javascript\nmodule-type: command\n\nCommand to render several tiddlers to a folder of files\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar widget = require(\"$:/core/modules/widgets/widget.js\");\n\nexports.info = {\n\tname: \"rendertiddlers\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(this.params.length < 2) {\n\t\treturn \"Missing filename\";\n\t}\n\tvar self = this,\n\t\tfs = require(\"fs\"),\n\t\tpath = require(\"path\"),\n\t\twiki = this.commander.wiki,\n\t\tfilter = this.params[0],\n\t\ttemplate = this.params[1],\n\t\toutputPath = this.commander.outputPath,\n\t\tpathname = path.resolve(outputPath,this.params[2]),\t\t\n\t\ttype = this.params[3] || \"text/html\",\n\t\textension = this.params[4] || \".html\",\n\t\tdeleteDirectory = (this.params[5] || \"\").toLowerCase() !== \"noclean\",\n\t\ttiddlers = wiki.filterTiddlers(filter);\n\tif(deleteDirectory) {\n\t\t$tw.utils.deleteDirectory(pathname);\n\t}\n\t$tw.utils.each(tiddlers,function(title) {\n\t\tvar parser = wiki.parseTiddler(template),\n\t\t\twidgetNode = wiki.makeWidget(parser,{variables: {currentTiddler: title}}),\n\t\t\tcontainer = $tw.fakeDocument.createElement(\"div\");\n\t\twidgetNode.render(container,null);\n\t\tvar text = type === \"text/html\" ? container.innerHTML : container.textContent,\n\t\t\texportPath = null;\n\t\tif($tw.utils.hop($tw.macros,\"tv-get-export-path\")) {\n\t\t\tvar macroPath = $tw.macros[\"tv-get-export-path\"].run.apply(self,[title]);\n\t\t\tif(macroPath) {\n\t\t\t\texportPath = path.resolve(outputPath,macroPath + extension);\n\t\t\t}\n\t\t}\n\t\tvar finalPath = exportPath || path.resolve(pathname,encodeURIComponent(title) + extension);\n\t\t$tw.utils.createFileDirectories(finalPath);\n\t\tfs.writeFileSync(finalPath,text,\"utf8\");\n\t});\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/commands/save.js": {
"title": "$:/core/modules/commands/save.js",
"text": "/*\\\ntitle: $:/core/modules/commands/save.js\ntype: application/javascript\nmodule-type: command\n\nSaves individual tiddlers in their raw text or binary format to the specified files\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"save\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(this.params.length < 1) {\n\t\treturn \"Missing filename filter\";\n\t}\n\tvar self = this,\n\t\tfs = require(\"fs\"),\n\t\tpath = require(\"path\"),\n\t\twiki = this.commander.wiki,\n\t\ttiddlerFilter = this.params[0],\n\t\tfilenameFilter = this.params[1] || \"[is[tiddler]]\",\n\t\ttiddlers = wiki.filterTiddlers(tiddlerFilter);\n\t$tw.utils.each(tiddlers,function(title) {\n\t\tvar tiddler = self.commander.wiki.getTiddler(title),\n\t\t\ttype = tiddler.fields.type || \"text/vnd.tiddlywiki\",\n\t\t\tcontentTypeInfo = $tw.config.contentTypeInfo[type] || {encoding: \"utf8\"},\n\t\t\tfilepath = path.resolve(self.commander.outputPath,wiki.filterTiddlers(filenameFilter,$tw.rootWidget,wiki.makeTiddlerIterator([title]))[0]);\n\t\tif(self.commander.verbose) {\n\t\t\tconsole.log(\"Saving \\\"\" + title + \"\\\" to \\\"\" + filepath + \"\\\"\");\n\t\t}\n\t\t$tw.utils.createFileDirectories(filepath);\n\t\tfs.writeFileSync(filepath,tiddler.fields.text,contentTypeInfo.encoding);\n\t});\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/commands/savelibrarytiddlers.js": {
"title": "$:/core/modules/commands/savelibrarytiddlers.js",
"text": "/*\\\ntitle: $:/core/modules/commands/savelibrarytiddlers.js\ntype: application/javascript\nmodule-type: command\n\nCommand to save the subtiddlers of a bundle tiddler as a series of JSON files\n\n--savelibrarytiddlers <tiddler> <pathname> <skinnylisting>\n\nThe tiddler identifies the bundle tiddler that contains the subtiddlers.\n\nThe pathname specifies the pathname to the folder in which the JSON files should be saved. The filename is the URL encoded title of the subtiddler.\n\nThe skinnylisting specifies the title of the tiddler to which a JSON catalogue of the subtiddlers will be saved. The JSON file contains the same data as the bundle tiddler but with the `text` field removed.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"savelibrarytiddlers\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(this.params.length < 2) {\n\t\treturn \"Missing filename\";\n\t}\n\tvar self = this,\n\t\tfs = require(\"fs\"),\n\t\tpath = require(\"path\"),\n\t\tcontainerTitle = this.params[0],\n\t\tfilter = this.params[1],\n\t\tbasepath = this.params[2],\n\t\tskinnyListTitle = this.params[3];\n\t// Get the container tiddler as data\n\tvar containerData = self.commander.wiki.getTiddlerDataCached(containerTitle,undefined);\n\tif(!containerData) {\n\t\treturn \"'\" + containerTitle + \"' is not a tiddler bundle\";\n\t}\n\t// Filter the list of plugins\n\tvar pluginList = [];\n\t$tw.utils.each(containerData.tiddlers,function(tiddler,title) {\n\t\tpluginList.push(title);\n\t});\n\tvar filteredPluginList;\n\tif(filter) {\n\t\tfilteredPluginList = self.commander.wiki.filterTiddlers(filter,null,self.commander.wiki.makeTiddlerIterator(pluginList));\n\t} else {\n\t\tfilteredPluginList = pluginList;\n\t}\n\t// Iterate through the plugins\n\tvar skinnyList = [];\n\t$tw.utils.each(filteredPluginList,function(title) {\n\t\tvar tiddler = containerData.tiddlers[title];\n\t\t// Save each JSON file and collect the skinny data\n\t\tvar pathname = path.resolve(self.commander.outputPath,basepath + encodeURIComponent(title) + \".json\");\n\t\t$tw.utils.createFileDirectories(pathname);\n\t\tfs.writeFileSync(pathname,JSON.stringify(tiddler,null,$tw.config.preferences.jsonSpaces),\"utf8\");\n\t\t// Collect the skinny list data\n\t\tvar pluginTiddlers = JSON.parse(tiddler.text),\n\t\t\treadmeContent = (pluginTiddlers.tiddlers[title + \"/readme\"] || {}).text,\n\t\t\ticonTiddler = pluginTiddlers.tiddlers[title + \"/icon\"] || {},\n\t\t\ticonType = iconTiddler.type,\n\t\t\ticonText = iconTiddler.text,\n\t\t\ticonContent;\n\t\tif(iconType && iconText) {\n\t\t\ticonContent = $tw.utils.makeDataUri(iconText,iconType);\n\t\t}\n\t\tskinnyList.push($tw.utils.extend({},tiddler,{text: undefined, readme: readmeContent, icon: iconContent}));\n\t});\n\t// Save the catalogue tiddler\n\tif(skinnyListTitle) {\n\t\tself.commander.wiki.setTiddlerData(skinnyListTitle,skinnyList);\n\t}\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/commands/savetiddler.js": {
"title": "$:/core/modules/commands/savetiddler.js",
"text": "/*\\\ntitle: $:/core/modules/commands/savetiddler.js\ntype: application/javascript\nmodule-type: command\n\nCommand to save the content of a tiddler to a file\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"savetiddler\",\n\tsynchronous: false\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(this.params.length < 2) {\n\t\treturn \"Missing filename\";\n\t}\n\tvar self = this,\n\t\tfs = require(\"fs\"),\n\t\tpath = require(\"path\"),\n\t\ttitle = this.params[0],\n\t\tfilename = path.resolve(this.commander.outputPath,this.params[1]),\n\t\ttiddler = this.commander.wiki.getTiddler(title);\n\tif(tiddler) {\n\t\tvar type = tiddler.fields.type || \"text/vnd.tiddlywiki\",\n\t\t\tcontentTypeInfo = $tw.config.contentTypeInfo[type] || {encoding: \"utf8\"};\n\t\t$tw.utils.createFileDirectories(filename);\n\t\tfs.writeFile(filename,tiddler.fields.text,contentTypeInfo.encoding,function(err) {\n\t\t\tself.callback(err);\n\t\t});\n\t} else {\n\t\treturn \"Missing tiddler: \" + title;\n\t}\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/commands/savetiddlers.js": {
"title": "$:/core/modules/commands/savetiddlers.js",
"text": "/*\\\ntitle: $:/core/modules/commands/savetiddlers.js\ntype: application/javascript\nmodule-type: command\n\nCommand to save several tiddlers to a folder of files\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar widget = require(\"$:/core/modules/widgets/widget.js\");\n\nexports.info = {\n\tname: \"savetiddlers\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(this.params.length < 1) {\n\t\treturn \"Missing filename\";\n\t}\n\tvar self = this,\n\t\tfs = require(\"fs\"),\n\t\tpath = require(\"path\"),\n\t\twiki = this.commander.wiki,\n\t\tfilter = this.params[0],\n\t\tpathname = path.resolve(this.commander.outputPath,this.params[1]),\n\t\tdeleteDirectory = (this.params[2] || \"\").toLowerCase() !== \"noclean\",\n\t\ttiddlers = wiki.filterTiddlers(filter);\n\tif(deleteDirectory) {\n\t\t$tw.utils.deleteDirectory(pathname);\n\t}\n\t$tw.utils.createDirectory(pathname);\n\t$tw.utils.each(tiddlers,function(title) {\n\t\tvar tiddler = self.commander.wiki.getTiddler(title),\n\t\t\ttype = tiddler.fields.type || \"text/vnd.tiddlywiki\",\n\t\t\tcontentTypeInfo = $tw.config.contentTypeInfo[type] || {encoding: \"utf8\"},\n\t\t\tfilename = path.resolve(pathname,encodeURIComponent(title));\n\t\tfs.writeFileSync(filename,tiddler.fields.text,contentTypeInfo.encoding);\n\t});\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/commands/server.js": {
"title": "$:/core/modules/commands/server.js",
"text": "/*\\\ntitle: $:/core/modules/commands/server.js\ntype: application/javascript\nmodule-type: command\n\nDeprecated legacy command for serving tiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Server = require(\"$:/core/modules/server/server.js\").Server;\n\nexports.info = {\n\tname: \"server\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander,callback) {\n\tvar self = this;\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(!$tw.boot.wikiTiddlersPath) {\n\t\t$tw.utils.warning(\"Warning: Wiki folder '\" + $tw.boot.wikiPath + \"' does not exist or is missing a tiddlywiki.info file\");\n\t}\n\t// Set up server\n\tthis.server = new Server({\n\t\twiki: this.commander.wiki,\n\t\tvariables: {\n\t\t\tport: this.params[0],\n\t\t\thost: this.params[6],\n\t\t\t\"root-tiddler\": this.params[1],\n\t\t\t\"root-render-type\": this.params[2],\n\t\t\t\"root-serve-type\": this.params[3],\n\t\t\tusername: this.params[4],\n\t\t\tpassword: this.params[5],\n\t\t\t\"path-prefix\": this.params[7],\n\t\t\t\"debug-level\": this.params[8]\n\t\t}\n\t});\n\tvar nodeServer = this.server.listen();\n\t$tw.hooks.invokeHook(\"th-server-command-post-start\",this.server,nodeServer,\"tiddlywiki\");\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/commands/setfield.js": {
"title": "$:/core/modules/commands/setfield.js",
"text": "/*\\\ntitle: $:/core/modules/commands/setfield.js\ntype: application/javascript\nmodule-type: command\n\nCommand to modify selected tiddlers to set a field to the text of a template tiddler that has been wikified with the selected tiddler as the current tiddler.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar widget = require(\"$:/core/modules/widgets/widget.js\");\n\nexports.info = {\n\tname: \"setfield\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(this.params.length < 4) {\n\t\treturn \"Missing parameters\";\n\t}\n\tvar self = this,\n\t\twiki = this.commander.wiki,\n\t\tfilter = this.params[0],\n\t\tfieldname = this.params[1] || \"text\",\n\t\ttemplatetitle = this.params[2],\n\t\trendertype = this.params[3] || \"text/plain\",\n\t\ttiddlers = wiki.filterTiddlers(filter);\n\t$tw.utils.each(tiddlers,function(title) {\n\t\tvar parser = wiki.parseTiddler(templatetitle),\n\t\t\tnewFields = {},\n\t\t\ttiddler = wiki.getTiddler(title);\n\t\tif(parser) {\n\t\t\tvar widgetNode = wiki.makeWidget(parser,{variables: {currentTiddler: title}});\n\t\t\tvar container = $tw.fakeDocument.createElement(\"div\");\n\t\t\twidgetNode.render(container,null);\n\t\t\tnewFields[fieldname] = rendertype === \"text/html\" ? container.innerHTML : container.textContent;\n\t\t} else {\n\t\t\tnewFields[fieldname] = undefined;\n\t\t}\n\t\twiki.addTiddler(new $tw.Tiddler(tiddler,newFields));\n\t});\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/commands/unpackplugin.js": {
"title": "$:/core/modules/commands/unpackplugin.js",
"text": "/*\\\ntitle: $:/core/modules/commands/unpackplugin.js\ntype: application/javascript\nmodule-type: command\n\nCommand to extract the shadow tiddlers from within a plugin\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"unpackplugin\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(this.params.length < 1) {\n\t\treturn \"Missing plugin name\";\n\t}\n\tvar self = this,\n\t\ttitle = this.params[0],\n\t\tpluginData = this.commander.wiki.getTiddlerDataCached(title);\n\tif(!pluginData) {\n\t\treturn \"Plugin '\" + title + \"' not found\";\n\t}\n\t$tw.utils.each(pluginData.tiddlers,function(tiddler) {\n\t\tself.commander.wiki.addTiddler(new $tw.Tiddler(tiddler));\n\t});\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/commands/verbose.js": {
"title": "$:/core/modules/commands/verbose.js",
"text": "/*\\\ntitle: $:/core/modules/commands/verbose.js\ntype: application/javascript\nmodule-type: command\n\nVerbose command\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"verbose\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander) {\n\tthis.params = params;\n\tthis.commander = commander;\n};\n\nCommand.prototype.execute = function() {\n\tthis.commander.verbose = true;\n\t// Output the boot message log\n\tthis.commander.streams.output.write(\"Boot log:\\n \" + $tw.boot.logMessages.join(\"\\n \") + \"\\n\");\n\treturn null; // No error\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/commands/version.js": {
"title": "$:/core/modules/commands/version.js",
"text": "/*\\\ntitle: $:/core/modules/commands/version.js\ntype: application/javascript\nmodule-type: command\n\nVersion command\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"version\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander) {\n\tthis.params = params;\n\tthis.commander = commander;\n};\n\nCommand.prototype.execute = function() {\n\tthis.commander.streams.output.write($tw.version + \"\\n\");\n\treturn null; // No error\n};\n\nexports.Command = Command;\n\n})();\n",
"type": "application/javascript",
"module-type": "command"
},
"$:/core/modules/config.js": {
"title": "$:/core/modules/config.js",
"text": "/*\\\ntitle: $:/core/modules/config.js\ntype: application/javascript\nmodule-type: config\n\nCore configuration constants\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.preferences = {};\n\nexports.preferences.notificationDuration = 3 * 1000;\nexports.preferences.jsonSpaces = 4;\n\nexports.textPrimitives = {\n\tupperLetter: \"[A-Z\\u00c0-\\u00d6\\u00d8-\\u00de\\u0150\\u0170]\",\n\tlowerLetter: \"[a-z\\u00df-\\u00f6\\u00f8-\\u00ff\\u0151\\u0171]\",\n\tanyLetter: \"[A-Za-z0-9\\u00c0-\\u00d6\\u00d8-\\u00de\\u00df-\\u00f6\\u00f8-\\u00ff\\u0150\\u0170\\u0151\\u0171]\",\n\tblockPrefixLetters:\t\"[A-Za-z0-9-_\\u00c0-\\u00d6\\u00d8-\\u00de\\u00df-\\u00f6\\u00f8-\\u00ff\\u0150\\u0170\\u0151\\u0171]\"\n};\n\nexports.textPrimitives.unWikiLink = \"~\";\nexports.textPrimitives.wikiLink = exports.textPrimitives.upperLetter + \"+\" +\n\texports.textPrimitives.lowerLetter + \"+\" +\n\texports.textPrimitives.upperLetter +\n\texports.textPrimitives.anyLetter + \"*\";\n\nexports.htmlEntities = {quot:34, amp:38, apos:39, lt:60, gt:62, nbsp:160, iexcl:161, cent:162, pound:163, curren:164, yen:165, brvbar:166, sect:167, uml:168, copy:169, ordf:170, laquo:171, not:172, shy:173, reg:174, macr:175, deg:176, plusmn:177, sup2:178, sup3:179, acute:180, micro:181, para:182, middot:183, cedil:184, sup1:185, ordm:186, raquo:187, frac14:188, frac12:189, frac34:190, iquest:191, Agrave:192, Aacute:193, Acirc:194, Atilde:195, Auml:196, Aring:197, AElig:198, Ccedil:199, Egrave:200, Eacute:201, Ecirc:202, Euml:203, Igrave:204, Iacute:205, Icirc:206, Iuml:207, ETH:208, Ntilde:209, Ograve:210, Oacute:211, Ocirc:212, Otilde:213, Ouml:214, times:215, Oslash:216, Ugrave:217, Uacute:218, Ucirc:219, Uuml:220, Yacute:221, THORN:222, szlig:223, agrave:224, aacute:225, acirc:226, atilde:227, auml:228, aring:229, aelig:230, ccedil:231, egrave:232, eacute:233, ecirc:234, euml:235, igrave:236, iacute:237, icirc:238, iuml:239, eth:240, ntilde:241, ograve:242, oacute:243, ocirc:244, otilde:245, ouml:246, divide:247, oslash:248, ugrave:249, uacute:250, ucirc:251, uuml:252, yacute:253, thorn:254, yuml:255, OElig:338, oelig:339, Scaron:352, scaron:353, Yuml:376, fnof:402, circ:710, tilde:732, Alpha:913, Beta:914, Gamma:915, Delta:916, Epsilon:917, Zeta:918, Eta:919, Theta:920, Iota:921, Kappa:922, Lambda:923, Mu:924, Nu:925, Xi:926, Omicron:927, Pi:928, Rho:929, Sigma:931, Tau:932, Upsilon:933, Phi:934, Chi:935, Psi:936, Omega:937, alpha:945, beta:946, gamma:947, delta:948, epsilon:949, zeta:950, eta:951, theta:952, iota:953, kappa:954, lambda:955, mu:956, nu:957, xi:958, omicron:959, pi:960, rho:961, sigmaf:962, sigma:963, tau:964, upsilon:965, phi:966, chi:967, psi:968, omega:969, thetasym:977, upsih:978, piv:982, ensp:8194, emsp:8195, thinsp:8201, zwnj:8204, zwj:8205, lrm:8206, rlm:8207, ndash:8211, mdash:8212, lsquo:8216, rsquo:8217, sbquo:8218, ldquo:8220, rdquo:8221, bdquo:8222, dagger:8224, Dagger:8225, bull:8226, hellip:8230, permil:8240, prime:8242, Prime:8243, lsaquo:8249, rsaquo:8250, oline:8254, frasl:8260, euro:8364, image:8465, weierp:8472, real:8476, trade:8482, alefsym:8501, larr:8592, uarr:8593, rarr:8594, darr:8595, harr:8596, crarr:8629, lArr:8656, uArr:8657, rArr:8658, dArr:8659, hArr:8660, forall:8704, part:8706, exist:8707, empty:8709, nabla:8711, isin:8712, notin:8713, ni:8715, prod:8719, sum:8721, minus:8722, lowast:8727, radic:8730, prop:8733, infin:8734, ang:8736, and:8743, or:8744, cap:8745, cup:8746, int:8747, there4:8756, sim:8764, cong:8773, asymp:8776, ne:8800, equiv:8801, le:8804, ge:8805, sub:8834, sup:8835, nsub:8836, sube:8838, supe:8839, oplus:8853, otimes:8855, perp:8869, sdot:8901, lceil:8968, rceil:8969, lfloor:8970, rfloor:8971, lang:9001, rang:9002, loz:9674, spades:9824, clubs:9827, hearts:9829, diams:9830 };\n\nexports.htmlVoidElements = \"area,base,br,col,command,embed,hr,img,input,keygen,link,meta,param,source,track,wbr\".split(\",\");\n\nexports.htmlBlockElements = \"address,article,aside,audio,blockquote,canvas,dd,div,dl,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,hr,li,noscript,ol,output,p,pre,section,table,tfoot,ul,video\".split(\",\");\n\nexports.htmlUnsafeElements = \"script\".split(\",\");\n\n})();\n",
"type": "application/javascript",
"module-type": "config"
},
"$:/core/modules/deserializers.js": {
"title": "$:/core/modules/deserializers.js",
"text": "/*\\\ntitle: $:/core/modules/deserializers.js\ntype: application/javascript\nmodule-type: tiddlerdeserializer\n\nFunctions to deserialise tiddlers from a block of text\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nUtility function to parse an old-style tiddler DIV in a *.tid file. It looks like this:\n\n<div title=\"Title\" creator=\"JoeBloggs\" modifier=\"JoeBloggs\" created=\"201102111106\" modified=\"201102111310\" tags=\"myTag [[my long tag]]\">\n<pre>The text of the tiddler (without the expected HTML encoding).\n</pre>\n</div>\n\nNote that the field attributes are HTML encoded, but that the body of the <PRE> tag is not encoded.\n\nWhen these tiddler DIVs are encountered within a TiddlyWiki HTML file then the body is encoded in the usual way.\n*/\nvar parseTiddlerDiv = function(text /* [,fields] */) {\n\t// Slot together the default results\n\tvar result = {};\n\tif(arguments.length > 1) {\n\t\tfor(var f=1; f<arguments.length; f++) {\n\t\t\tvar fields = arguments[f];\n\t\t\tfor(var t in fields) {\n\t\t\t\tresult[t] = fields[t];\t\t\n\t\t\t}\n\t\t}\n\t}\n\t// Parse the DIV body\n\tvar startRegExp = /^\\s*<div\\s+([^>]*)>(\\s*<pre>)?/gi,\n\t\tendRegExp,\n\t\tmatch = startRegExp.exec(text);\n\tif(match) {\n\t\t// Old-style DIVs don't have the <pre> tag\n\t\tif(match[2]) {\n\t\t\tendRegExp = /<\\/pre>\\s*<\\/div>\\s*$/gi;\n\t\t} else {\n\t\t\tendRegExp = /<\\/div>\\s*$/gi;\n\t\t}\n\t\tvar endMatch = endRegExp.exec(text);\n\t\tif(endMatch) {\n\t\t\t// Extract the text\n\t\t\tresult.text = text.substring(match.index + match[0].length,endMatch.index);\n\t\t\t// Process the attributes\n\t\t\tvar attrRegExp = /\\s*([^=\\s]+)\\s*=\\s*(?:\"([^\"]*)\"|'([^']*)')/gi,\n\t\t\t\tattrMatch;\n\t\t\tdo {\n\t\t\t\tattrMatch = attrRegExp.exec(match[1]);\n\t\t\t\tif(attrMatch) {\n\t\t\t\t\tvar name = attrMatch[1];\n\t\t\t\t\tvar value = attrMatch[2] !== undefined ? attrMatch[2] : attrMatch[3];\n\t\t\t\t\tresult[name] = value;\n\t\t\t\t}\n\t\t\t} while(attrMatch);\n\t\t\treturn result;\n\t\t}\n\t}\n\treturn undefined;\n};\n\nexports[\"application/x-tiddler-html-div\"] = function(text,fields) {\n\treturn [parseTiddlerDiv(text,fields)];\n};\n\nexports[\"application/json\"] = function(text,fields) {\n\tvar incoming,\n\t\tresults = [];\n\ttry {\n\t\tincoming = JSON.parse(text);\n\t} catch(e) {\n\t\tincoming = [{\n\t\t\ttitle: \"JSON error: \" + e,\n\t\t\ttext: \"\"\n\t\t}]\n\t}\n\tif(!$tw.utils.isArray(incoming)) {\n\t\tincoming = [incoming];\n\t}\n\tfor(var t=0; t<incoming.length; t++) {\n\t\tvar incomingFields = incoming[t],\n\t\t\tfields = {};\n\t\tfor(var f in incomingFields) {\n\t\t\tif(typeof incomingFields[f] === \"string\") {\n\t\t\t\tfields[f] = incomingFields[f];\n\t\t\t}\n\t\t}\n\t\tresults.push(fields);\n\t}\n\treturn results;\n};\n\n/*\nParse an HTML file into tiddlers. There are three possibilities:\n# A TiddlyWiki classic HTML file containing `text/x-tiddlywiki` tiddlers\n# A TiddlyWiki5 HTML file containing `text/vnd.tiddlywiki` tiddlers\n# An ordinary HTML file\n*/\nexports[\"text/html\"] = function(text,fields) {\n\t// Check if we've got a store area\n\tvar storeAreaMarkerRegExp = /<div id=[\"']?storeArea['\"]?( style=[\"']?display:none;[\"']?)?>/gi,\n\t\tmatch = storeAreaMarkerRegExp.exec(text);\n\tif(match) {\n\t\t// If so, it's either a classic TiddlyWiki file or an unencrypted TW5 file\n\t\t// First read the normal tiddlers\n\t\tvar results = deserializeTiddlyWikiFile(text,storeAreaMarkerRegExp.lastIndex,!!match[1],fields);\n\t\t// Then any system tiddlers\n\t\tvar systemAreaMarkerRegExp = /<div id=[\"']?systemArea['\"]?( style=[\"']?display:none;[\"']?)?>/gi,\n\t\t\tsysMatch = systemAreaMarkerRegExp.exec(text);\n\t\tif(sysMatch) {\n\t\t\tresults.push.apply(results,deserializeTiddlyWikiFile(text,systemAreaMarkerRegExp.lastIndex,!!sysMatch[1],fields));\n\t\t}\n\t\treturn results;\n\t} else {\n\t\t// Check whether we've got an encrypted file\n\t\tvar encryptedStoreArea = $tw.utils.extractEncryptedStoreArea(text);\n\t\tif(encryptedStoreArea) {\n\t\t\t// If so, attempt to decrypt it using the current password\n\t\t\treturn $tw.utils.decryptStoreArea(encryptedStoreArea);\n\t\t} else {\n\t\t\t// It's not a TiddlyWiki so we'll return the entire HTML file as a tiddler\n\t\t\treturn deserializeHtmlFile(text,fields);\n\t\t}\n\t}\n};\n\nfunction deserializeHtmlFile(text,fields) {\n\tvar result = {};\n\t$tw.utils.each(fields,function(value,name) {\n\t\tresult[name] = value;\n\t});\n\tresult.text = text;\n\tresult.type = \"text/html\";\n\treturn [result];\n}\n\nfunction deserializeTiddlyWikiFile(text,storeAreaEnd,isTiddlyWiki5,fields) {\n\tvar results = [],\n\t\tendOfDivRegExp = /(<\\/div>\\s*)/gi,\n\t\tstartPos = storeAreaEnd,\n\t\tdefaultType = isTiddlyWiki5 ? undefined : \"text/x-tiddlywiki\";\n\tendOfDivRegExp.lastIndex = startPos;\n\tvar match = endOfDivRegExp.exec(text);\n\twhile(match) {\n\t\tvar endPos = endOfDivRegExp.lastIndex,\n\t\t\ttiddlerFields = parseTiddlerDiv(text.substring(startPos,endPos),fields,{type: defaultType});\n\t\tif(!tiddlerFields) {\n\t\t\tbreak;\n\t\t}\n\t\t$tw.utils.each(tiddlerFields,function(value,name) {\n\t\t\tif(typeof value === \"string\") {\n\t\t\t\ttiddlerFields[name] = $tw.utils.htmlDecode(value);\n\t\t\t}\n\t\t});\n\t\tif(tiddlerFields.text !== null) {\n\t\t\tresults.push(tiddlerFields);\n\t\t}\n\t\tstartPos = endPos;\n\t\tmatch = endOfDivRegExp.exec(text);\n\t}\n\treturn results;\n}\n\n})();\n",
"type": "application/javascript",
"module-type": "tiddlerdeserializer"
},
"$:/core/modules/editor/engines/framed.js": {
"title": "$:/core/modules/editor/engines/framed.js",
"text": "/*\\\ntitle: $:/core/modules/editor/engines/framed.js\ntype: application/javascript\nmodule-type: library\n\nText editor engine based on a simple input or textarea within an iframe. This is done so that the selection is preserved even when clicking away from the textarea\n\n\\*/\n(function(){\n\n/*jslint node: true,browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar HEIGHT_VALUE_TITLE = \"$:/config/TextEditor/EditorHeight/Height\";\n\nfunction FramedEngine(options) {\n\t// Save our options\n\toptions = options || {};\n\tthis.widget = options.widget;\n\tthis.value = options.value;\n\tthis.parentNode = options.parentNode;\n\tthis.nextSibling = options.nextSibling;\n\t// Create our hidden dummy text area for reading styles\n\tthis.dummyTextArea = this.widget.document.createElement(\"textarea\");\n\tif(this.widget.editClass) {\n\t\tthis.dummyTextArea.className = this.widget.editClass;\n\t}\n\tthis.dummyTextArea.setAttribute(\"hidden\",\"true\");\n\tthis.parentNode.insertBefore(this.dummyTextArea,this.nextSibling);\n\tthis.widget.domNodes.push(this.dummyTextArea);\n\t// Create the iframe\n\tthis.iframeNode = this.widget.document.createElement(\"iframe\");\n\tthis.parentNode.insertBefore(this.iframeNode,this.nextSibling);\n\tthis.iframeDoc = this.iframeNode.contentWindow.document;\n\t// (Firefox requires us to put some empty content in the iframe)\n\tthis.iframeDoc.open();\n\tthis.iframeDoc.write(\"\");\n\tthis.iframeDoc.close();\n\t// Style the iframe\n\tthis.iframeNode.className = this.dummyTextArea.className;\n\tthis.iframeNode.style.border = \"none\";\n\tthis.iframeNode.style.padding = \"0\";\n\tthis.iframeNode.style.resize = \"none\";\n\tthis.iframeDoc.body.style.margin = \"0\";\n\tthis.iframeDoc.body.style.padding = \"0\";\n\tthis.widget.domNodes.push(this.iframeNode);\n\t// Construct the textarea or input node\n\tvar tag = this.widget.editTag;\n\tif($tw.config.htmlUnsafeElements.indexOf(tag) !== -1) {\n\t\ttag = \"input\";\n\t}\n\tthis.domNode = this.iframeDoc.createElement(tag);\n\t// Set the text\n\tif(this.widget.editTag === \"textarea\") {\n\t\tthis.domNode.appendChild(this.iframeDoc.createTextNode(this.value));\n\t} else {\n\t\tthis.domNode.value = this.value;\n\t}\n\t// Set the attributes\n\tif(this.widget.editType) {\n\t\tthis.domNode.setAttribute(\"type\",this.widget.editType);\n\t}\n\tif(this.widget.editPlaceholder) {\n\t\tthis.domNode.setAttribute(\"placeholder\",this.widget.editPlaceholder);\n\t}\n\tif(this.widget.editSize) {\n\t\tthis.domNode.setAttribute(\"size\",this.widget.editSize);\n\t}\n\tif(this.widget.editRows) {\n\t\tthis.domNode.setAttribute(\"rows\",this.widget.editRows);\n\t}\n\t// Copy the styles from the dummy textarea\n\tthis.copyStyles();\n\t// Add event listeners\n\t$tw.utils.addEventListeners(this.domNode,[\n\t\t{name: \"click\",handlerObject: this,handlerMethod: \"handleClickEvent\"},\n\t\t{name: \"input\",handlerObject: this,handlerMethod: \"handleInputEvent\"},\n\t\t{name: \"keydown\",handlerObject: this.widget,handlerMethod: \"handleKeydownEvent\"}\n\t]);\n\t// Insert the element into the DOM\n\tthis.iframeDoc.body.appendChild(this.domNode);\n}\n\n/*\nCopy styles from the dummy text area to the textarea in the iframe\n*/\nFramedEngine.prototype.copyStyles = function() {\n\t// Copy all styles\n\t$tw.utils.copyStyles(this.dummyTextArea,this.domNode);\n\t// Override the ones that should not be set the same as the dummy textarea\n\tthis.domNode.style.display = \"block\";\n\tthis.domNode.style.width = \"100%\";\n\tthis.domNode.style.margin = \"0\";\n\t// In Chrome setting -webkit-text-fill-color overrides the placeholder text colour\n\tthis.domNode.style[\"-webkit-text-fill-color\"] = \"currentcolor\";\n};\n\n/*\nSet the text of the engine if it doesn't currently have focus\n*/\nFramedEngine.prototype.setText = function(text,type) {\n\tif(!this.domNode.isTiddlyWikiFakeDom) {\n\t\tif(this.domNode.ownerDocument.activeElement !== this.domNode) {\n\t\t\tthis.domNode.value = text;\n\t\t}\n\t\t// Fix the height if needed\n\t\tthis.fixHeight();\n\t}\n};\n\n/*\nGet the text of the engine\n*/\nFramedEngine.prototype.getText = function() {\n\treturn this.domNode.value;\n};\n\n/*\nFix the height of textarea to fit content\n*/\nFramedEngine.prototype.fixHeight = function() {\n\t// Make sure styles are updated\n\tthis.copyStyles();\n\t// Adjust height\n\tif(this.widget.editTag === \"textarea\") {\n\t\tif(this.widget.editAutoHeight) {\n\t\t\tif(this.domNode && !this.domNode.isTiddlyWikiFakeDom) {\n\t\t\t\tvar newHeight = $tw.utils.resizeTextAreaToFit(this.domNode,this.widget.editMinHeight);\n\t\t\t\tthis.iframeNode.style.height = (newHeight + 14) + \"px\"; // +14 for the border on the textarea\n\t\t\t}\n\t\t} else {\n\t\t\tvar fixedHeight = parseInt(this.widget.wiki.getTiddlerText(HEIGHT_VALUE_TITLE,\"400px\"),10);\n\t\t\tfixedHeight = Math.max(fixedHeight,20);\n\t\t\tthis.domNode.style.height = fixedHeight + \"px\";\n\t\t\tthis.iframeNode.style.height = (fixedHeight + 14) + \"px\";\n\t\t}\n\t}\n};\n\n/*\nFocus the engine node\n*/\nFramedEngine.prototype.focus = function() {\n\tif(this.domNode.focus && this.domNode.select) {\n\t\tthis.domNode.focus();\n\t\tthis.domNode.select();\n\t}\n};\n\n/*\nHandle a click\n*/\nFramedEngine.prototype.handleClickEvent = function(event) {\n\tthis.fixHeight();\n\treturn true;\n};\n\n/*\nHandle a dom \"input\" event which occurs when the text has changed\n*/\nFramedEngine.prototype.handleInputEvent = function(event) {\n\tthis.widget.saveChanges(this.getText());\n\tthis.fixHeight();\n\treturn true;\n};\n\n/*\nCreate a blank structure representing a text operation\n*/\nFramedEngine.prototype.createTextOperation = function() {\n\tvar operation = {\n\t\ttext: this.domNode.value,\n\t\tselStart: this.domNode.selectionStart,\n\t\tselEnd: this.domNode.selectionEnd,\n\t\tcutStart: null,\n\t\tcutEnd: null,\n\t\treplacement: null,\n\t\tnewSelStart: null,\n\t\tnewSelEnd: null\n\t};\n\toperation.selection = operation.text.substring(operation.selStart,operation.selEnd);\n\treturn operation;\n};\n\n/*\nExecute a text operation\n*/\nFramedEngine.prototype.executeTextOperation = function(operation) {\n\t// Perform the required changes to the text area and the underlying tiddler\n\tvar newText = operation.text;\n\tif(operation.replacement !== null) {\n\t\tnewText = operation.text.substring(0,operation.cutStart) + operation.replacement + operation.text.substring(operation.cutEnd);\n\t\t// Attempt to use a execCommand to modify the value of the control\n\t\tif(this.iframeDoc.queryCommandSupported(\"insertText\") && this.iframeDoc.queryCommandSupported(\"delete\") && !$tw.browser.isFirefox) {\n\t\t\tthis.domNode.focus();\n\t\t\tthis.domNode.setSelectionRange(operation.cutStart,operation.cutEnd);\n\t\t\tif(operation.replacement === \"\") {\n\t\t\t\tthis.iframeDoc.execCommand(\"delete\",false,\"\");\n\t\t\t} else {\n\t\t\t\tthis.iframeDoc.execCommand(\"insertText\",false,operation.replacement);\n\t\t\t}\n\t\t} else {\n\t\t\tthis.domNode.value = newText;\n\t\t}\n\t\tthis.domNode.focus();\n\t\tthis.domNode.setSelectionRange(operation.newSelStart,operation.newSelEnd);\n\t}\n\tthis.domNode.focus();\n\treturn newText;\n};\n\nexports.FramedEngine = FramedEngine;\n\n})();\n",
"type": "application/javascript",
"module-type": "library"
},
"$:/core/modules/editor/engines/simple.js": {
"title": "$:/core/modules/editor/engines/simple.js",
"text": "/*\\\ntitle: $:/core/modules/editor/engines/simple.js\ntype: application/javascript\nmodule-type: library\n\nText editor engine based on a simple input or textarea tag\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar HEIGHT_VALUE_TITLE = \"$:/config/TextEditor/EditorHeight/Height\";\n\nfunction SimpleEngine(options) {\n\t// Save our options\n\toptions = options || {};\n\tthis.widget = options.widget;\n\tthis.value = options.value;\n\tthis.parentNode = options.parentNode;\n\tthis.nextSibling = options.nextSibling;\n\t// Construct the textarea or input node\n\tvar tag = this.widget.editTag;\n\tif($tw.config.htmlUnsafeElements.indexOf(tag) !== -1) {\n\t\ttag = \"input\";\n\t}\n\tthis.domNode = this.widget.document.createElement(tag);\n\t// Set the text\n\tif(this.widget.editTag === \"textarea\") {\n\t\tthis.domNode.appendChild(this.widget.document.createTextNode(this.value));\n\t} else {\n\t\tthis.domNode.value = this.value;\n\t}\n\t// Set the attributes\n\tif(this.widget.editType) {\n\t\tthis.domNode.setAttribute(\"type\",this.widget.editType);\n\t}\n\tif(this.widget.editPlaceholder) {\n\t\tthis.domNode.setAttribute(\"placeholder\",this.widget.editPlaceholder);\n\t}\n\tif(this.widget.editSize) {\n\t\tthis.domNode.setAttribute(\"size\",this.widget.editSize);\n\t}\n\tif(this.widget.editRows) {\n\t\tthis.domNode.setAttribute(\"rows\",this.widget.editRows);\n\t}\n\tif(this.widget.editClass) {\n\t\tthis.domNode.className = this.widget.editClass;\n\t}\n\t// Add an input event handler\n\t$tw.utils.addEventListeners(this.domNode,[\n\t\t{name: \"focus\", handlerObject: this, handlerMethod: \"handleFocusEvent\"},\n\t\t{name: \"input\", handlerObject: this, handlerMethod: \"handleInputEvent\"}\n\t]);\n\t// Insert the element into the DOM\n\tthis.parentNode.insertBefore(this.domNode,this.nextSibling);\n\tthis.widget.domNodes.push(this.domNode);\n}\n\n/*\nSet the text of the engine if it doesn't currently have focus\n*/\nSimpleEngine.prototype.setText = function(text,type) {\n\tif(!this.domNode.isTiddlyWikiFakeDom) {\n\t\tif(this.domNode.ownerDocument.activeElement !== this.domNode || text === \"\") {\n\t\t\tthis.domNode.value = text;\n\t\t}\n\t\t// Fix the height if needed\n\t\tthis.fixHeight();\n\t}\n};\n\n/*\nGet the text of the engine\n*/\nSimpleEngine.prototype.getText = function() {\n\treturn this.domNode.value;\n};\n\n/*\nFix the height of textarea to fit content\n*/\nSimpleEngine.prototype.fixHeight = function() {\n\tif(this.widget.editTag === \"textarea\") {\n\t\tif(this.widget.editAutoHeight) {\n\t\t\tif(this.domNode && !this.domNode.isTiddlyWikiFakeDom) {\n\t\t\t\t$tw.utils.resizeTextAreaToFit(this.domNode,this.widget.editMinHeight);\n\t\t\t}\n\t\t} else {\n\t\t\tvar fixedHeight = parseInt(this.widget.wiki.getTiddlerText(HEIGHT_VALUE_TITLE,\"400px\"),10);\n\t\t\tfixedHeight = Math.max(fixedHeight,20);\n\t\t\tthis.domNode.style.height = fixedHeight + \"px\";\n\t\t}\n\t}\n};\n\n/*\nFocus the engine node\n*/\nSimpleEngine.prototype.focus = function() {\n\tif(this.domNode.focus && this.domNode.select) {\n\t\tthis.domNode.focus();\n\t\tthis.domNode.select();\n\t}\n};\n\n/*\nHandle a dom \"input\" event which occurs when the text has changed\n*/\nSimpleEngine.prototype.handleInputEvent = function(event) {\n\tthis.widget.saveChanges(this.getText());\n\tthis.fixHeight();\n\treturn true;\n};\n\n/*\nHandle a dom \"focus\" event\n*/\nSimpleEngine.prototype.handleFocusEvent = function(event) {\n\tif(this.widget.editFocusPopup) {\n\t\t$tw.popup.triggerPopup({\n\t\t\tdomNode: this.domNode,\n\t\t\ttitle: this.widget.editFocusPopup,\n\t\t\twiki: this.widget.wiki,\n\t\t\tforce: true\n\t\t});\n\t}\n\treturn true;\n};\n\n/*\nCreate a blank structure representing a text operation\n*/\nSimpleEngine.prototype.createTextOperation = function() {\n\treturn null;\n};\n\n/*\nExecute a text operation\n*/\nSimpleEngine.prototype.executeTextOperation = function(operation) {\n};\n\nexports.SimpleEngine = SimpleEngine;\n\n})();\n",
"type": "application/javascript",
"module-type": "library"
},
"$:/core/modules/editor/factory.js": {
"title": "$:/core/modules/editor/factory.js",
"text": "/*\\\ntitle: $:/core/modules/editor/factory.js\ntype: application/javascript\nmodule-type: library\n\nFactory for constructing text editor widgets with specified engines for the toolbar and non-toolbar cases\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar DEFAULT_MIN_TEXT_AREA_HEIGHT = \"100px\"; // Minimum height of textareas in pixels\n\n// Configuration tiddlers\nvar HEIGHT_MODE_TITLE = \"$:/config/TextEditor/EditorHeight/Mode\";\nvar ENABLE_TOOLBAR_TITLE = \"$:/config/TextEditor/EnableToolbar\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nfunction editTextWidgetFactory(toolbarEngine,nonToolbarEngine) {\n\n\tvar EditTextWidget = function(parseTreeNode,options) {\n\t\t// Initialise the editor operations if they've not been done already\n\t\tif(!this.editorOperations) {\n\t\t\tEditTextWidget.prototype.editorOperations = {};\n\t\t\t$tw.modules.applyMethods(\"texteditoroperation\",this.editorOperations);\n\t\t}\n\t\tthis.initialise(parseTreeNode,options);\n\t};\n\n\t/*\n\tInherit from the base widget class\n\t*/\n\tEditTextWidget.prototype = new Widget();\n\n\t/*\n\tRender this widget into the DOM\n\t*/\n\tEditTextWidget.prototype.render = function(parent,nextSibling) {\n\t\t// Save the parent dom node\n\t\tthis.parentDomNode = parent;\n\t\t// Compute our attributes\n\t\tthis.computeAttributes();\n\t\t// Execute our logic\n\t\tthis.execute();\n\t\t// Create the wrapper for the toolbar and render its content\n\t\tif(this.editShowToolbar) {\n\t\t\tthis.toolbarNode = this.document.createElement(\"div\");\n\t\t\tthis.toolbarNode.className = \"tc-editor-toolbar\";\n\t\t\tparent.insertBefore(this.toolbarNode,nextSibling);\n\t\t\tthis.renderChildren(this.toolbarNode,null);\n\t\t\tthis.domNodes.push(this.toolbarNode);\n\t\t}\n\t\t// Create our element\n\t\tvar editInfo = this.getEditInfo(),\n\t\t\tEngine = this.editShowToolbar ? toolbarEngine : nonToolbarEngine;\n\t\tthis.engine = new Engine({\n\t\t\t\twidget: this,\n\t\t\t\tvalue: editInfo.value,\n\t\t\t\ttype: editInfo.type,\n\t\t\t\tparentNode: parent,\n\t\t\t\tnextSibling: nextSibling\n\t\t\t});\n\t\t// Call the postRender hook\n\t\tif(this.postRender) {\n\t\t\tthis.postRender();\n\t\t}\n\t\t// Fix height\n\t\tthis.engine.fixHeight();\n\t\t// Focus if required\n\t\tif(this.editFocus === \"true\" || this.editFocus === \"yes\") {\n\t\t\tthis.engine.focus();\n\t\t}\n\t\t// Add widget message listeners\n\t\tthis.addEventListeners([\n\t\t\t{type: \"tm-edit-text-operation\", handler: \"handleEditTextOperationMessage\"}\n\t\t]);\n\t};\n\n\t/*\n\tGet the tiddler being edited and current value\n\t*/\n\tEditTextWidget.prototype.getEditInfo = function() {\n\t\t// Get the edit value\n\t\tvar self = this,\n\t\t\tvalue,\n\t\t\ttype = \"text/plain\",\n\t\t\tupdate;\n\t\tif(this.editIndex) {\n\t\t\tvalue = this.wiki.extractTiddlerDataItem(this.editTitle,this.editIndex,this.editDefault);\n\t\t\tupdate = function(value) {\n\t\t\t\tvar data = self.wiki.getTiddlerData(self.editTitle,{});\n\t\t\t\tif(data[self.editIndex] !== value) {\n\t\t\t\t\tdata[self.editIndex] = value;\n\t\t\t\t\tself.wiki.setTiddlerData(self.editTitle,data);\n\t\t\t\t}\n\t\t\t};\n\t\t} else {\n\t\t\t// Get the current tiddler and the field name\n\t\t\tvar tiddler = this.wiki.getTiddler(this.editTitle);\n\t\t\tif(tiddler) {\n\t\t\t\t// If we've got a tiddler, the value to display is the field string value\n\t\t\t\tvalue = tiddler.getFieldString(this.editField);\n\t\t\t\tif(this.editField === \"text\") {\n\t\t\t\t\ttype = tiddler.fields.type || \"text/vnd.tiddlywiki\";\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Otherwise, we need to construct a default value for the editor\n\t\t\t\tswitch(this.editField) {\n\t\t\t\t\tcase \"text\":\n\t\t\t\t\t\tvalue = \"Type the text for the tiddler '\" + this.editTitle + \"'\";\n\t\t\t\t\t\ttype = \"text/vnd.tiddlywiki\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"title\":\n\t\t\t\t\t\tvalue = this.editTitle;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tvalue = \"\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif(this.editDefault !== undefined) {\n\t\t\t\t\tvalue = this.editDefault;\n\t\t\t\t}\n\t\t\t}\n\t\t\tupdate = function(value) {\n\t\t\t\tvar tiddler = self.wiki.getTiddler(self.editTitle),\n\t\t\t\t\tupdateFields = {\n\t\t\t\t\t\ttitle: self.editTitle\n\t\t\t\t\t};\n\t\t\t\tupdateFields[self.editField] = value;\n\t\t\t\tself.wiki.addTiddler(new $tw.Tiddler(self.wiki.getCreationFields(),tiddler,updateFields,self.wiki.getModificationFields()));\n\t\t\t};\n\t\t}\n\t\tif(this.editType) {\n\t\t\ttype = this.editType;\n\t\t}\n\t\treturn {value: value || \"\", type: type, update: update};\n\t};\n\n\t/*\n\tHandle an edit text operation message from the toolbar\n\t*/\n\tEditTextWidget.prototype.handleEditTextOperationMessage = function(event) {\n\t\t// Prepare information about the operation\n\t\tvar operation = this.engine.createTextOperation();\n\t\t// Invoke the handler for the selected operation\n\t\tvar handler = this.editorOperations[event.param];\n\t\tif(handler) {\n\t\t\thandler.call(this,event,operation);\n\t\t}\n\t\t// Execute the operation via the engine\n\t\tvar newText = this.engine.executeTextOperation(operation);\n\t\t// Fix the tiddler height and save changes\n\t\tthis.engine.fixHeight();\n\t\tthis.saveChanges(newText);\n\t};\n\n\t/*\n\tCompute the internal state of the widget\n\t*/\n\tEditTextWidget.prototype.execute = function() {\n\t\t// Get our parameters\n\t\tthis.editTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\t\tthis.editField = this.getAttribute(\"field\",\"text\");\n\t\tthis.editIndex = this.getAttribute(\"index\");\n\t\tthis.editDefault = this.getAttribute(\"default\");\n\t\tthis.editClass = this.getAttribute(\"class\");\n\t\tthis.editPlaceholder = this.getAttribute(\"placeholder\");\n\t\tthis.editSize = this.getAttribute(\"size\");\n\t\tthis.editRows = this.getAttribute(\"rows\");\n\t\tthis.editAutoHeight = this.wiki.getTiddlerText(HEIGHT_MODE_TITLE,\"auto\");\n\t\tthis.editAutoHeight = this.getAttribute(\"autoHeight\",this.editAutoHeight === \"auto\" ? \"yes\" : \"no\") === \"yes\";\n\t\tthis.editMinHeight = this.getAttribute(\"minHeight\",DEFAULT_MIN_TEXT_AREA_HEIGHT);\n\t\tthis.editFocusPopup = this.getAttribute(\"focusPopup\");\n\t\tthis.editFocus = this.getAttribute(\"focus\");\n\t\t// Get the default editor element tag and type\n\t\tvar tag,type;\n\t\tif(this.editField === \"text\") {\n\t\t\ttag = \"textarea\";\n\t\t} else {\n\t\t\ttag = \"input\";\n\t\t\tvar fieldModule = $tw.Tiddler.fieldModules[this.editField];\n\t\t\tif(fieldModule && fieldModule.editTag) {\n\t\t\t\ttag = fieldModule.editTag;\n\t\t\t}\n\t\t\tif(fieldModule && fieldModule.editType) {\n\t\t\t\ttype = fieldModule.editType;\n\t\t\t}\n\t\t\ttype = type || \"text\";\n\t\t}\n\t\t// Get the rest of our parameters\n\t\tthis.editTag = this.getAttribute(\"tag\",tag);\n\t\tthis.editType = this.getAttribute(\"type\",type);\n\t\t// Make the child widgets\n\t\tthis.makeChildWidgets();\n\t\t// Determine whether to show the toolbar\n\t\tthis.editShowToolbar = this.wiki.getTiddlerText(ENABLE_TOOLBAR_TITLE,\"yes\");\n\t\tthis.editShowToolbar = (this.editShowToolbar === \"yes\") && !!(this.children && this.children.length > 0) && (!this.document.isTiddlyWikiFakeDom);\n\t};\n\n\t/*\n\tSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n\t*/\n\tEditTextWidget.prototype.refresh = function(changedTiddlers) {\n\t\tvar changedAttributes = this.computeAttributes();\n\t\t// Completely rerender if any of our attributes have changed\n\t\tif(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes[\"default\"] || changedAttributes[\"class\"] || changedAttributes.placeholder || changedAttributes.size || changedAttributes.autoHeight || changedAttributes.minHeight || changedAttributes.focusPopup || changedAttributes.rows || changedTiddlers[HEIGHT_MODE_TITLE] || changedTiddlers[ENABLE_TOOLBAR_TITLE]) {\n\t\t\tthis.refreshSelf();\n\t\t\treturn true;\n\t\t} else if(changedTiddlers[this.editTitle]) {\n\t\t\tvar editInfo = this.getEditInfo();\n\t\t\tthis.updateEditor(editInfo.value,editInfo.type);\n\t\t}\n\t\tthis.engine.fixHeight();\n\t\tif(this.editShowToolbar) {\n\t\t\treturn this.refreshChildren(changedTiddlers);\t\t\t\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t};\n\n\t/*\n\tUpdate the editor with new text. This method is separate from updateEditorDomNode()\n\tso that subclasses can override updateEditor() and still use updateEditorDomNode()\n\t*/\n\tEditTextWidget.prototype.updateEditor = function(text,type) {\n\t\tthis.updateEditorDomNode(text,type);\n\t};\n\n\t/*\n\tUpdate the editor dom node with new text\n\t*/\n\tEditTextWidget.prototype.updateEditorDomNode = function(text,type) {\n\t\tthis.engine.setText(text,type);\n\t};\n\n\t/*\n\tSave changes back to the tiddler store\n\t*/\n\tEditTextWidget.prototype.saveChanges = function(text) {\n\t\tvar editInfo = this.getEditInfo();\n\t\tif(text !== editInfo.value) {\n\t\t\teditInfo.update(text);\n\t\t}\n\t};\n\n\t/*\n\tHandle a dom \"keydown\" event, which we'll bubble up to our container for the keyboard widgets benefit\n\t*/\n\tEditTextWidget.prototype.handleKeydownEvent = function(event) {\n\t\t// Check for a keyboard shortcut\n\t\tif(this.toolbarNode) {\n\t\t\tvar shortcutElements = this.toolbarNode.querySelectorAll(\"[data-tw-keyboard-shortcut]\");\n\t\t\tfor(var index=0; index<shortcutElements.length; index++) {\n\t\t\t\tvar el = shortcutElements[index],\n\t\t\t\t\tshortcutData = el.getAttribute(\"data-tw-keyboard-shortcut\"),\n\t\t\t\t\tkeyInfoArray = $tw.keyboardManager.parseKeyDescriptors(shortcutData,{\n\t\t\t\t\t\twiki: this.wiki\n\t\t\t\t\t});\n\t\t\t\tif($tw.keyboardManager.checkKeyDescriptors(event,keyInfoArray)) {\n\t\t\t\t\tvar clickEvent = this.document.createEvent(\"Events\");\n\t\t\t\t clickEvent.initEvent(\"click\",true,false);\n\t\t\t\t el.dispatchEvent(clickEvent);\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\treturn true;\t\t\t\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// Propogate the event to the container\n\t\tif(this.propogateKeydownEvent(event)) {\n\t\t\t// Ignore the keydown if it was already handled\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\t\t\treturn true;\n\t\t}\n\t\t// Otherwise, process the keydown normally\n\t\treturn false;\n\t};\n\n\t/*\n\tPropogate keydown events to our container for the keyboard widgets benefit\n\t*/\n\tEditTextWidget.prototype.propogateKeydownEvent = function(event) {\n\t\tvar newEvent = this.document.createEventObject ? this.document.createEventObject() : this.document.createEvent(\"Events\");\n\t\tif(newEvent.initEvent) {\n\t\t\tnewEvent.initEvent(\"keydown\", true, true);\n\t\t}\n\t\tnewEvent.keyCode = event.keyCode;\n\t\tnewEvent.which = event.which;\n\t\tnewEvent.metaKey = event.metaKey;\n\t\tnewEvent.ctrlKey = event.ctrlKey;\n\t\tnewEvent.altKey = event.altKey;\n\t\tnewEvent.shiftKey = event.shiftKey;\n\t\treturn !this.parentDomNode.dispatchEvent(newEvent);\n\t};\n\n\treturn EditTextWidget;\n\n}\n\nexports.editTextWidgetFactory = editTextWidgetFactory;\n\n})();\n",
"type": "application/javascript",
"module-type": "library"
},
"$:/core/modules/editor/operations/bitmap/clear.js": {
"title": "$:/core/modules/editor/operations/bitmap/clear.js",
"text": "/*\\\ntitle: $:/core/modules/editor/operations/bitmap/clear.js\ntype: application/javascript\nmodule-type: bitmapeditoroperation\n\nBitmap editor operation to clear the image\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports[\"clear\"] = function(event) {\n\tvar ctx = this.canvasDomNode.getContext(\"2d\");\n\tctx.globalAlpha = 1;\n\tctx.fillStyle = event.paramObject.colour || \"white\";\n\tctx.fillRect(0,0,this.canvasDomNode.width,this.canvasDomNode.height);\n\t// Save changes\n\tthis.strokeEnd();\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "bitmapeditoroperation"
},
"$:/core/modules/editor/operations/bitmap/resize.js": {
"title": "$:/core/modules/editor/operations/bitmap/resize.js",
"text": "/*\\\ntitle: $:/core/modules/editor/operations/bitmap/resize.js\ntype: application/javascript\nmodule-type: bitmapeditoroperation\n\nBitmap editor operation to resize the image\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports[\"resize\"] = function(event) {\n\t// Get the new width\n\tvar newWidth = parseInt(event.paramObject.width || this.canvasDomNode.width,10),\n\t\tnewHeight = parseInt(event.paramObject.height || this.canvasDomNode.height,10);\n\t// Update if necessary\n\tif(newWidth > 0 && newHeight > 0 && !(newWidth === this.currCanvas.width && newHeight === this.currCanvas.height)) {\n\t\tthis.changeCanvasSize(newWidth,newHeight);\n\t}\n\t// Update the input controls\n\tthis.refreshToolbar();\n\t// Save the image into the tiddler\n\tthis.saveChanges();\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "bitmapeditoroperation"
},
"$:/core/modules/editor/operations/bitmap/rotate-left.js": {
"title": "$:/core/modules/editor/operations/bitmap/rotate-left.js",
"text": "/*\\\ntitle: $:/core/modules/editor/operations/bitmap/rotate-left.js\ntype: application/javascript\nmodule-type: bitmapeditoroperation\n\nBitmap editor operation to rotate the image left by 90 degrees\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports[\"rotate-left\"] = function(event) {\n\t// Rotate the canvas left by 90 degrees\n\tthis.rotateCanvasLeft();\n\t// Update the input controls\n\tthis.refreshToolbar();\n\t// Save the image into the tiddler\n\tthis.saveChanges();\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "bitmapeditoroperation"
},
"$:/core/modules/editor/operations/text/excise.js": {
"title": "$:/core/modules/editor/operations/text/excise.js",
"text": "/*\\\ntitle: $:/core/modules/editor/operations/text/excise.js\ntype: application/javascript\nmodule-type: texteditoroperation\n\nText editor operation to excise the selection to a new tiddler\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports[\"excise\"] = function(event,operation) {\n\tvar editTiddler = this.wiki.getTiddler(this.editTitle),\n\t\teditTiddlerTitle = this.editTitle;\n\tif(editTiddler && editTiddler.fields[\"draft.of\"]) {\n\t\teditTiddlerTitle = editTiddler.fields[\"draft.of\"];\n\t}\n\tvar excisionTitle = event.paramObject.title || this.wiki.generateNewTitle(\"New Excision\");\n\tthis.wiki.addTiddler(new $tw.Tiddler(\n\t\tthis.wiki.getCreationFields(),\n\t\tthis.wiki.getModificationFields(),\n\t\t{\n\t\t\ttitle: excisionTitle,\n\t\t\ttext: operation.selection,\n\t\t\ttags: event.paramObject.tagnew === \"yes\" ? [editTiddlerTitle] : []\n\t\t}\n\t));\n\toperation.replacement = excisionTitle;\n\tswitch(event.paramObject.type || \"transclude\") {\n\t\tcase \"transclude\":\n\t\t\toperation.replacement = \"{{\" + operation.replacement+ \"}}\";\n\t\t\tbreak;\n\t\tcase \"link\":\n\t\t\toperation.replacement = \"[[\" + operation.replacement+ \"]]\";\n\t\t\tbreak;\n\t\tcase \"macro\":\n\t\t\toperation.replacement = \"<<\" + (event.paramObject.macro || \"translink\") + \" \\\"\\\"\\\"\" + operation.replacement + \"\\\"\\\"\\\">>\";\n\t\t\tbreak;\n\t}\n\toperation.cutStart = operation.selStart;\n\toperation.cutEnd = operation.selEnd;\n\toperation.newSelStart = operation.selStart;\n\toperation.newSelEnd = operation.selStart + operation.replacement.length;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "texteditoroperation"
},
"$:/core/modules/editor/operations/text/make-link.js": {
"title": "$:/core/modules/editor/operations/text/make-link.js",
"text": "/*\\\ntitle: $:/core/modules/editor/operations/text/make-link.js\ntype: application/javascript\nmodule-type: texteditoroperation\n\nText editor operation to make a link\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports[\"make-link\"] = function(event,operation) {\n\tif(operation.selection) {\n\t\toperation.replacement = \"[[\" + operation.selection + \"|\" + event.paramObject.text + \"]]\";\n\t\toperation.cutStart = operation.selStart;\n\t\toperation.cutEnd = operation.selEnd;\n\t} else {\n\t\toperation.replacement = \"[[\" + event.paramObject.text + \"]]\";\n\t\toperation.cutStart = operation.selStart;\n\t\toperation.cutEnd = operation.selEnd;\n\t}\n\toperation.newSelStart = operation.selStart + operation.replacement.length;\n\toperation.newSelEnd = operation.newSelStart;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "texteditoroperation"
},
"$:/core/modules/editor/operations/text/prefix-lines.js": {
"title": "$:/core/modules/editor/operations/text/prefix-lines.js",
"text": "/*\\\ntitle: $:/core/modules/editor/operations/text/prefix-lines.js\ntype: application/javascript\nmodule-type: texteditoroperation\n\nText editor operation to add a prefix to the selected lines\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports[\"prefix-lines\"] = function(event,operation) {\n\t// Cut just past the preceding line break, or the start of the text\n\toperation.cutStart = $tw.utils.findPrecedingLineBreak(operation.text,operation.selStart);\n\t// Cut to just past the following line break, or to the end of the text\n\toperation.cutEnd = $tw.utils.findFollowingLineBreak(operation.text,operation.selEnd);\n\t// Compose the required prefix\n\tvar prefix = $tw.utils.repeat(event.paramObject.character,event.paramObject.count);\n\t// Process each line\n\tvar lines = operation.text.substring(operation.cutStart,operation.cutEnd).split(/\\r?\\n/mg);\n\t$tw.utils.each(lines,function(line,index) {\n\t\t// Remove and count any existing prefix characters\n\t\tvar count = 0;\n\t\twhile(line.charAt(0) === event.paramObject.character) {\n\t\t\tline = line.substring(1);\n\t\t\tcount++;\n\t\t}\n\t\t// Remove any whitespace\n\t\twhile(line.charAt(0) === \" \") {\n\t\t\tline = line.substring(1);\n\t\t}\n\t\t// We're done if we removed the exact required prefix, otherwise add it\n\t\tif(count !== event.paramObject.count) {\n\t\t\t// Apply the prefix\n\t\t\tline = prefix + \" \" + line;\n\t\t}\n\t\t// Save the modified line\n\t\tlines[index] = line;\n\t});\n\t// Stitch the replacement text together and set the selection\n\toperation.replacement = lines.join(\"\\n\");\n\tif(lines.length === 1) {\n\t\toperation.newSelStart = operation.cutStart + operation.replacement.length;\n\t\toperation.newSelEnd = operation.newSelStart;\n\t} else {\n\t\toperation.newSelStart = operation.cutStart;\n\t\toperation.newSelEnd = operation.newSelStart + operation.replacement.length;\n\t}\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "texteditoroperation"
},
"$:/core/modules/editor/operations/text/replace-all.js": {
"title": "$:/core/modules/editor/operations/text/replace-all.js",
"text": "/*\\\ntitle: $:/core/modules/editor/operations/text/replace-all.js\ntype: application/javascript\nmodule-type: texteditoroperation\n\nText editor operation to replace the entire text\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports[\"replace-all\"] = function(event,operation) {\n\toperation.cutStart = 0;\n\toperation.cutEnd = operation.text.length;\n\toperation.replacement = event.paramObject.text;\n\toperation.newSelStart = 0;\n\toperation.newSelEnd = operation.replacement.length;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "texteditoroperation"
},
"$:/core/modules/editor/operations/text/replace-selection.js": {
"title": "$:/core/modules/editor/operations/text/replace-selection.js",
"text": "/*\\\ntitle: $:/core/modules/editor/operations/text/replace-selection.js\ntype: application/javascript\nmodule-type: texteditoroperation\n\nText editor operation to replace the selection\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports[\"replace-selection\"] = function(event,operation) {\n\toperation.replacement = event.paramObject.text;\n\toperation.cutStart = operation.selStart;\n\toperation.cutEnd = operation.selEnd;\n\toperation.newSelStart = operation.selStart;\n\toperation.newSelEnd = operation.selStart + operation.replacement.length;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "texteditoroperation"
},
"$:/core/modules/editor/operations/text/save-selection.js": {
"title": "$:/core/modules/editor/operations/text/save-selection.js",
"text": "/*\\\ntitle: $:/core/modules/editor/operations/text/save-selection.js\ntype: application/javascript\nmodule-type: texteditoroperation\n\nText editor operation to save the current selection in a specified tiddler\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports[\"save-selection\"] = function(event,operation) {\n\tvar tiddler = event.paramObject.tiddler,\n\t\tfield = event.paramObject.field || \"text\";\n\tif(tiddler && field) {\n\t\tthis.wiki.setText(tiddler,field,null,operation.text.substring(operation.selStart,operation.selEnd));\n\t}\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "texteditoroperation"
},
"$:/core/modules/editor/operations/text/wrap-lines.js": {
"title": "$:/core/modules/editor/operations/text/wrap-lines.js",
"text": "/*\\\ntitle: $:/core/modules/editor/operations/text/wrap-lines.js\ntype: application/javascript\nmodule-type: texteditoroperation\n\nText editor operation to wrap the selected lines with a prefix and suffix\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports[\"wrap-lines\"] = function(event,operation) {\n\t// Cut just past the preceding line break, or the start of the text\n\toperation.cutStart = $tw.utils.findPrecedingLineBreak(operation.text,operation.selStart);\n\t// Cut to just past the following line break, or to the end of the text\n\toperation.cutEnd = $tw.utils.findFollowingLineBreak(operation.text,operation.selEnd);\n\t// Add the prefix and suffix\n\toperation.replacement = event.paramObject.prefix + \"\\n\" +\n\t\t\t\toperation.text.substring(operation.cutStart,operation.cutEnd) + \"\\n\" +\n\t\t\t\tevent.paramObject.suffix + \"\\n\";\n\toperation.newSelStart = operation.cutStart + event.paramObject.prefix.length + 1;\n\toperation.newSelEnd = operation.newSelStart + (operation.cutEnd - operation.cutStart);\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "texteditoroperation"
},
"$:/core/modules/editor/operations/text/wrap-selection.js": {
"title": "$:/core/modules/editor/operations/text/wrap-selection.js",
"text": "/*\\\ntitle: $:/core/modules/editor/operations/text/wrap-selection.js\ntype: application/javascript\nmodule-type: texteditoroperation\n\nText editor operation to wrap the selection with the specified prefix and suffix\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports[\"wrap-selection\"] = function(event,operation) {\n\tif(operation.selStart === operation.selEnd) {\n\t\t// No selection; check if we're within the prefix/suffix\n\t\tif(operation.text.substring(operation.selStart - event.paramObject.prefix.length,operation.selStart + event.paramObject.suffix.length) === event.paramObject.prefix + event.paramObject.suffix) {\n\t\t\t// Remove the prefix and suffix unless they comprise the entire text\n\t\t\tif(operation.selStart > event.paramObject.prefix.length || (operation.selEnd + event.paramObject.suffix.length) < operation.text.length ) {\n\t\t\t\toperation.cutStart = operation.selStart - event.paramObject.prefix.length;\n\t\t\t\toperation.cutEnd = operation.selEnd + event.paramObject.suffix.length;\n\t\t\t\toperation.replacement = \"\";\n\t\t\t\toperation.newSelStart = operation.cutStart;\n\t\t\t\toperation.newSelEnd = operation.newSelStart;\n\t\t\t}\n\t\t} else {\n\t\t\t// Wrap the cursor instead\n\t\t\toperation.cutStart = operation.selStart;\n\t\t\toperation.cutEnd = operation.selEnd;\n\t\t\toperation.replacement = event.paramObject.prefix + event.paramObject.suffix;\n\t\t\toperation.newSelStart = operation.selStart + event.paramObject.prefix.length;\n\t\t\toperation.newSelEnd = operation.newSelStart;\n\t\t}\n\t} else if(operation.text.substring(operation.selStart,operation.selStart + event.paramObject.prefix.length) === event.paramObject.prefix && operation.text.substring(operation.selEnd - event.paramObject.suffix.length,operation.selEnd) === event.paramObject.suffix) {\n\t\t// Prefix and suffix are already present, so remove them\n\t\toperation.cutStart = operation.selStart;\n\t\toperation.cutEnd = operation.selEnd;\n\t\toperation.replacement = operation.selection.substring(event.paramObject.prefix.length,operation.selection.length - event.paramObject.suffix.length);\n\t\toperation.newSelStart = operation.selStart;\n\t\toperation.newSelEnd = operation.selStart + operation.replacement.length;\n\t} else {\n\t\t// Add the prefix and suffix\n\t\toperation.cutStart = operation.selStart;\n\t\toperation.cutEnd = operation.selEnd;\n\t\toperation.replacement = event.paramObject.prefix + operation.selection + event.paramObject.suffix;\n\t\toperation.newSelStart = operation.selStart;\n\t\toperation.newSelEnd = operation.selStart + operation.replacement.length;\n\t}\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "texteditoroperation"
},
"$:/core/modules/filters/addprefix.js": {
"title": "$:/core/modules/filters/addprefix.js",
"text": "/*\\\ntitle: $:/core/modules/filters/addprefix.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for adding a prefix to each title in the list. This is\nespecially useful in contexts where only a filter expression is allowed\nand macro substitution isn't available.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.addprefix = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(operator.operand + title);\n\t});\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/addsuffix.js": {
"title": "$:/core/modules/filters/addsuffix.js",
"text": "/*\\\ntitle: $:/core/modules/filters/addsuffix.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for adding a suffix to each title in the list. This is\nespecially useful in contexts where only a filter expression is allowed\nand macro substitution isn't available.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.addsuffix = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(title + operator.operand);\n\t});\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/after.js": {
"title": "$:/core/modules/filters/after.js",
"text": "/*\\\ntitle: $:/core/modules/filters/after.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning the tiddler from the current list that is after the tiddler named in the operand.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.after = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(title);\n\t});\n\tvar index = results.indexOf(operator.operand);\n\tif(index === -1 || index > (results.length - 2)) {\n\t\treturn [];\n\t} else {\n\t\treturn [results[index + 1]];\n\t}\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/all/current.js": {
"title": "$:/core/modules/filters/all/current.js",
"text": "/*\\\ntitle: $:/core/modules/filters/all/current.js\ntype: application/javascript\nmodule-type: allfilteroperator\n\nFilter function for [all[current]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.current = function(source,prefix,options) {\n\tvar currTiddlerTitle = options.widget && options.widget.getVariable(\"currentTiddler\");\n\tif(currTiddlerTitle) {\n\t\treturn [currTiddlerTitle];\n\t} else {\n\t\treturn [];\n\t}\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "allfilteroperator"
},
"$:/core/modules/filters/all/missing.js": {
"title": "$:/core/modules/filters/all/missing.js",
"text": "/*\\\ntitle: $:/core/modules/filters/all/missing.js\ntype: application/javascript\nmodule-type: allfilteroperator\n\nFilter function for [all[missing]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.missing = function(source,prefix,options) {\n\treturn options.wiki.getMissingTitles();\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "allfilteroperator"
},
"$:/core/modules/filters/all/orphans.js": {
"title": "$:/core/modules/filters/all/orphans.js",
"text": "/*\\\ntitle: $:/core/modules/filters/all/orphans.js\ntype: application/javascript\nmodule-type: allfilteroperator\n\nFilter function for [all[orphans]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.orphans = function(source,prefix,options) {\n\treturn options.wiki.getOrphanTitles();\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "allfilteroperator"
},
"$:/core/modules/filters/all/shadows.js": {
"title": "$:/core/modules/filters/all/shadows.js",
"text": "/*\\\ntitle: $:/core/modules/filters/all/shadows.js\ntype: application/javascript\nmodule-type: allfilteroperator\n\nFilter function for [all[shadows]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.shadows = function(source,prefix,options) {\n\treturn options.wiki.allShadowTitles();\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "allfilteroperator"
},
"$:/core/modules/filters/all/tags.js": {
"title": "$:/core/modules/filters/all/tags.js",
"text": "/*\\\ntitle: $:/core/modules/filters/all/tags.js\ntype: application/javascript\nmodule-type: allfilteroperator\n\nFilter function for [all[tags]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.tags = function(source,prefix,options) {\n\treturn Object.keys(options.wiki.getTagMap());\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "allfilteroperator"
},
"$:/core/modules/filters/all/tiddlers.js": {
"title": "$:/core/modules/filters/all/tiddlers.js",
"text": "/*\\\ntitle: $:/core/modules/filters/all/tiddlers.js\ntype: application/javascript\nmodule-type: allfilteroperator\n\nFilter function for [all[tiddlers]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.tiddlers = function(source,prefix,options) {\n\treturn options.wiki.allTitles();\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "allfilteroperator"
},
"$:/core/modules/filters/all.js": {
"title": "$:/core/modules/filters/all.js",
"text": "/*\\\ntitle: $:/core/modules/filters/all.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for selecting tiddlers\n\n[all[shadows+tiddlers]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar allFilterOperators;\n\nfunction getAllFilterOperators() {\n\tif(!allFilterOperators) {\n\t\tallFilterOperators = {};\n\t\t$tw.modules.applyMethods(\"allfilteroperator\",allFilterOperators);\n\t}\n\treturn allFilterOperators;\n}\n\n/*\nExport our filter function\n*/\nexports.all = function(source,operator,options) {\n\t// Get our suboperators\n\tvar allFilterOperators = getAllFilterOperators();\n\t// Cycle through the suboperators accumulating their results\n\tvar results = [],\n\t\tsubops = operator.operand.split(\"+\");\n\t// Check for common optimisations\n\tif(subops.length === 1 && subops[0] === \"\") {\n\t\treturn source;\n\t} else if(subops.length === 1 && subops[0] === \"tiddlers\") {\n\t\treturn options.wiki.each;\n\t} else if(subops.length === 1 && subops[0] === \"shadows\") {\n\t\treturn options.wiki.eachShadow;\n\t} else if(subops.length === 2 && subops[0] === \"tiddlers\" && subops[1] === \"shadows\") {\n\t\treturn options.wiki.eachTiddlerPlusShadows;\n\t} else if(subops.length === 2 && subops[0] === \"shadows\" && subops[1] === \"tiddlers\") {\n\t\treturn options.wiki.eachShadowPlusTiddlers;\n\t}\n\t// Do it the hard way\n\tfor(var t=0; t<subops.length; t++) {\n\t\tvar subop = allFilterOperators[subops[t]];\n\t\tif(subop) {\n\t\t\t$tw.utils.pushTop(results,subop(source,operator.prefix,options));\n\t\t}\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/backlinks.js": {
"title": "$:/core/modules/filters/backlinks.js",
"text": "/*\\\ntitle: $:/core/modules/filters/backlinks.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning all the backlinks from a tiddler\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.backlinks = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\t$tw.utils.pushTop(results,options.wiki.getTiddlerBacklinks(title));\n\t});\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/before.js": {
"title": "$:/core/modules/filters/before.js",
"text": "/*\\\ntitle: $:/core/modules/filters/before.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning the tiddler from the current list that is before the tiddler named in the operand.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.before = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(title);\n\t});\n\tvar index = results.indexOf(operator.operand);\n\tif(index <= 0) {\n\t\treturn [];\n\t} else {\n\t\treturn [results[index - 1]];\n\t}\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/commands.js": {
"title": "$:/core/modules/filters/commands.js",
"text": "/*\\\ntitle: $:/core/modules/filters/commands.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the names of the commands available in this wiki\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.commands = function(source,operator,options) {\n\tvar results = [];\n\t$tw.utils.each($tw.commands,function(commandInfo,name) {\n\t\tresults.push(name);\n\t});\n\tresults.sort();\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/contains.js": {
"title": "$:/core/modules/filters/contains.js",
"text": "/*\\\ntitle: $:/core/modules/filters/contains.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for finding values in array fields\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.contains = function(source,operator,options) {\n\tvar results = [],\n\t\tfieldname = (operator.suffix || \"list\").toLowerCase();\n\tif(operator.prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(tiddler) {\n\t\t\t\tvar list = tiddler.getFieldList(fieldname);\n\t\t\t\tif(list.indexOf(operator.operand) === -1) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(tiddler) {\n\t\t\t\tvar list = tiddler.getFieldList(fieldname);\n\t\t\t\tif(list.indexOf(operator.operand) !== -1) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/count.js": {
"title": "$:/core/modules/filters/count.js",
"text": "/*\\\ntitle: $:/core/modules/filters/count.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning the number of entries in the current list.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.count = function(source,operator,options) {\n\tvar count = 0;\n\tsource(function(tiddler,title) {\n\t\tcount++;\n\t});\n\treturn [count + \"\"];\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/days.js": {
"title": "$:/core/modules/filters/days.js",
"text": "/*\\\ntitle: $:/core/modules/filters/days.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator that selects tiddlers with a specified date field within a specified date interval.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.days = function(source,operator,options) {\n\tvar results = [],\n\t\tfieldName = operator.suffix || \"modified\",\n\t\tdayInterval = (parseInt(operator.operand,10)||0),\n\t\tdayIntervalSign = $tw.utils.sign(dayInterval),\n\t\ttargetTimeStamp = (new Date()).setHours(0,0,0,0) + 1000*60*60*24*dayInterval,\n\t\tisWithinDays = function(dateField) {\n\t\t\tvar sign = $tw.utils.sign(targetTimeStamp - (new Date(dateField)).setHours(0,0,0,0));\n\t\t\treturn sign === 0 || sign === dayIntervalSign;\n\t\t};\n\n\tif(operator.prefix === \"!\") {\n\t\ttargetTimeStamp = targetTimeStamp - 1000*60*60*24*dayIntervalSign;\n\t\tsource(function(tiddler,title) {\n\t\t\tif(tiddler && tiddler.fields[fieldName]) {\n\t\t\t\tif(!isWithinDays($tw.utils.parseDate(tiddler.fields[fieldName]))) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(tiddler && tiddler.fields[fieldName]) {\n\t\t\t\tif(isWithinDays($tw.utils.parseDate(tiddler.fields[fieldName]))) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/each.js": {
"title": "$:/core/modules/filters/each.js",
"text": "/*\\\ntitle: $:/core/modules/filters/each.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator that selects one tiddler for each unique value of the specified field.\nWith suffix \"list\", selects all tiddlers that are values in a specified list field.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.each = function(source,operator,options) {\n\tvar results =[] ,\n\tvalue,values = {},\n\tfield = operator.operand || \"title\";\n\tif(operator.suffix === \"value\" && field === \"title\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(!$tw.utils.hop(values,title)) {\n\t\t\t\tvalues[title] = true;\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else if(operator.suffix !== \"list-item\") {\n\t\tif(field === \"title\") {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(tiddler && !$tw.utils.hop(values,title)) {\n\t\t\t\t\tvalues[title] = true;\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(tiddler) {\n\t\t\t\t\tvalue = tiddler.getFieldString(field);\n\t\t\t\t\tif(!$tw.utils.hop(values,value)) {\n\t\t\t\t\t\tvalues[value] = true;\n\t\t\t\t\t\tresults.push(title);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(tiddler) {\n\t\t\t\t$tw.utils.each(\n\t\t\t\t\toptions.wiki.getTiddlerList(title,field),\n\t\t\t\t\tfunction(value) {\n\t\t\t\t\t\tif(!$tw.utils.hop(values,value)) {\n\t\t\t\t\t\t\tvalues[value] = true;\n\t\t\t\t\t\t\tresults.push(value);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/eachday.js": {
"title": "$:/core/modules/filters/eachday.js",
"text": "/*\\\ntitle: $:/core/modules/filters/eachday.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator that selects one tiddler for each unique day covered by the specified date field\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.eachday = function(source,operator,options) {\n\tvar results = [],\n\t\tvalues = [],\n\t\tfieldName = operator.operand || \"modified\";\n\t// Function to convert a date/time to a date integer\n\tvar toDate = function(value) {\n\t\tvalue = (new Date(value)).setHours(0,0,0,0);\n\t\treturn value+0;\n\t};\n\tsource(function(tiddler,title) {\n\t\tif(tiddler && tiddler.fields[fieldName]) {\n\t\t\tvar value = toDate($tw.utils.parseDate(tiddler.fields[fieldName]));\n\t\t\tif(values.indexOf(value) === -1) {\n\t\t\t\tvalues.push(value);\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t}\n\t});\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/editiondescription.js": {
"title": "$:/core/modules/filters/editiondescription.js",
"text": "/*\\\ntitle: $:/core/modules/filters/editiondescription.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the descriptions of the specified edition names\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.editiondescription = function(source,operator,options) {\n\tvar results = [],\n\t\teditionInfo = $tw.utils.getEditionInfo();\n\tif(editionInfo) {\n\t\tsource(function(tiddler,title) {\n\t\t\tif($tw.utils.hop(editionInfo,title)) {\n\t\t\t\tresults.push(editionInfo[title].description || \"\");\t\t\t\t\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/editions.js": {
"title": "$:/core/modules/filters/editions.js",
"text": "/*\\\ntitle: $:/core/modules/filters/editions.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the names of the available editions in this wiki\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.editions = function(source,operator,options) {\n\tvar results = [],\n\t\teditionInfo = $tw.utils.getEditionInfo();\n\tif(editionInfo) {\n\t\t$tw.utils.each(editionInfo,function(info,name) {\n\t\t\tresults.push(name);\n\t\t});\n\t}\n\tresults.sort();\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/decodeuricomponent.js": {
"title": "$:/core/modules/filters/decodeuricomponent.js",
"text": "/*\\\ntitle: $:/core/modules/filters/decodeuricomponent.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for applying decodeURIComponent() to each item.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter functions\n*/\n\nexports.decodeuricomponent = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tvar value = title;\n\t\ttry {\n\t\t\tvalue = decodeURIComponent(title);\n\t\t} catch(e) {\n\t\t}\n\t\tresults.push(value);\n\t});\n\treturn results;\n};\n\nexports.encodeuricomponent = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(encodeURIComponent(title));\n\t});\n\treturn results;\n};\n\nexports.decodeuri = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tvar value = title;\n\t\ttry {\n\t\t\tvalue = decodeURI(title);\n\t\t} catch(e) {\n\t\t}\n\t\tresults.push(value);\n\t});\n\treturn results;\n};\n\nexports.encodeuri = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(encodeURI(title));\n\t});\n\treturn results;\n};\n\nexports.decodehtml = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push($tw.utils.htmlDecode(title));\n\t});\n\treturn results;\n};\n\nexports.encodehtml = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push($tw.utils.htmlEncode(title));\n\t});\n\treturn results;\n};\n\nexports.stringify = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push($tw.utils.stringify(title));\n\t});\n\treturn results;\n};\n\nexports.jsonstringify = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push($tw.utils.jsonStringify(title));\n\t});\n\treturn results;\n};\n\nexports.escaperegexp = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push($tw.utils.escapeRegExp(title));\n\t});\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/enlist.js": {
"title": "$:/core/modules/filters/enlist.js",
"text": "/*\\\ntitle: $:/core/modules/filters/enlist.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning its operand parsed as a list\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.enlist = function(source,operator,options) {\n\tvar list = $tw.utils.parseStringArray(operator.operand);\n\tif(operator.prefix === \"!\") {\n\t\tvar results = [];\n\t\tsource(function(tiddler,title) {\n\t\t\tif(list.indexOf(title) === -1) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t\treturn results;\n\t} else {\n\t\treturn list;\n\t}\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/field.js": {
"title": "$:/core/modules/filters/field.js",
"text": "/*\\\ntitle: $:/core/modules/filters/field.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for comparing fields for equality\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.field = function(source,operator,options) {\n\tvar results = [],\n\t\tfieldname = (operator.suffix || operator.operator || \"title\").toLowerCase();\n\tif(operator.prefix === \"!\") {\n\t\tif(operator.regexp) {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(tiddler) {\n\t\t\t\t\tvar text = tiddler.getFieldString(fieldname);\n\t\t\t\t\tif(text !== null && !operator.regexp.exec(text)) {\n\t\t\t\t\t\tresults.push(title);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(tiddler) {\n\t\t\t\t\tvar text = tiddler.getFieldString(fieldname);\n\t\t\t\t\tif(text !== null && text !== operator.operand) {\n\t\t\t\t\t\tresults.push(title);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t} else {\n\t\tif(operator.regexp) {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(tiddler) {\n\t\t\t\t\tvar text = tiddler.getFieldString(fieldname);\n\t\t\t\t\tif(text !== null && !!operator.regexp.exec(text)) {\n\t\t\t\t\t\tresults.push(title);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(tiddler) {\n\t\t\t\t\tvar text = tiddler.getFieldString(fieldname);\n\t\t\t\t\tif(text !== null && text === operator.operand) {\n\t\t\t\t\t\tresults.push(title);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/fields.js": {
"title": "$:/core/modules/filters/fields.js",
"text": "/*\\\ntitle: $:/core/modules/filters/fields.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the names of the fields on the selected tiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.fields = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tif(tiddler) {\n\t\t\tfor(var fieldName in tiddler.fields) {\n\t\t\t\t$tw.utils.pushTop(results,fieldName);\n\t\t\t}\n\t\t}\n\t});\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/get.js": {
"title": "$:/core/modules/filters/get.js",
"text": "/*\\\ntitle: $:/core/modules/filters/get.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for replacing tiddler titles by the value of the field specified in the operand.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.get = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tif(tiddler) {\n\t\t\tvar value = tiddler.getFieldString(operator.operand);\n\t\t\tif(value) {\n\t\t\t\tresults.push(value);\n\t\t\t}\n\t\t}\n\t});\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/getindex.js": {
"title": "$:/core/modules/filters/getindex.js",
"text": "/*\\\ntitle: $:/core/modules/filters/getindex.js\ntype: application/javascript\nmodule-type: filteroperator\n\nreturns the value at a given index of datatiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.getindex = function(source,operator,options) {\n\tvar data,title,results = [];\n\tif(operator.operand){\n\t\tsource(function(tiddler,title) {\n\t\t\ttitle = tiddler ? tiddler.fields.title : title;\n\t\t\tdata = options.wiki.extractTiddlerDataItem(tiddler,operator.operand);\n\t\t\tif(data) {\n\t\t\t\tresults.push(data);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/has.js": {
"title": "$:/core/modules/filters/has.js",
"text": "/*\\\ntitle: $:/core/modules/filters/has.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for checking if a tiddler has the specified field\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.has = function(source,operator,options) {\n\tvar results = [],\n\t\tinvert = operator.prefix === \"!\";\n\n\tif(operator.suffix === \"field\") {\n\t\tif(invert) {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(!tiddler || (tiddler && (!$tw.utils.hop(tiddler.fields,operator.operand)))) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(tiddler && $tw.utils.hop(tiddler.fields,operator.operand)) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t} else {\n\t\tif(invert) {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(!tiddler || !$tw.utils.hop(tiddler.fields,operator.operand) || (tiddler.fields[operator.operand] === \"\")) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(tiddler && $tw.utils.hop(tiddler.fields,operator.operand) && !(tiddler.fields[operator.operand] === \"\" || tiddler.fields[operator.operand].length === 0)) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/haschanged.js": {
"title": "$:/core/modules/filters/haschanged.js",
"text": "/*\\\ntitle: $:/core/modules/filters/haschanged.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returns tiddlers from the list that have a non-zero changecount.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.haschanged = function(source,operator,options) {\n\tvar results = [];\n\tif(operator.prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(options.wiki.getChangeCount(title) === 0) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(options.wiki.getChangeCount(title) > 0) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/indexes.js": {
"title": "$:/core/modules/filters/indexes.js",
"text": "/*\\\ntitle: $:/core/modules/filters/indexes.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the indexes of a data tiddler\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.indexes = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tvar data = options.wiki.getTiddlerDataCached(title);\n\t\tif(data) {\n\t\t\t$tw.utils.pushTop(results,Object.keys(data));\n\t\t}\n\t});\n\tresults.sort();\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/insertbefore.js": {
"title": "$:/core/modules/filters/insertbefore.js",
"text": "/*\\\ntitle: $:/core/modules/filters/insertbefore.js\ntype: application/javascript\nmodule-type: filteroperator\n\nInsert an item before another item in a list\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nOrder a list\n*/\nexports.insertbefore = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(title);\n\t});\n\tvar target = options.widget && options.widget.getVariable(operator.suffix || \"currentTiddler\");\n\tif(target !== operator.operand) {\n\t\t// Remove the entry from the list if it is present\n\t\tvar pos = results.indexOf(operator.operand);\n\t\tif(pos !== -1) {\n\t\t\tresults.splice(pos,1);\n\t\t}\n\t\t// Insert the entry before the target marker\n\t\tpos = results.indexOf(target);\n\t\tif(pos !== -1) {\n\t\t\tresults.splice(pos,0,operator.operand);\n\t\t} else {\n\t\t\tresults.push(operator.operand);\n\t\t}\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/is/current.js": {
"title": "$:/core/modules/filters/is/current.js",
"text": "/*\\\ntitle: $:/core/modules/filters/is/current.js\ntype: application/javascript\nmodule-type: isfilteroperator\n\nFilter function for [is[current]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.current = function(source,prefix,options) {\n\tvar results = [],\n\t\tcurrTiddlerTitle = options.widget && options.widget.getVariable(\"currentTiddler\");\n\tif(prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(title !== currTiddlerTitle) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(title === currTiddlerTitle) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "isfilteroperator"
},
"$:/core/modules/filters/is/image.js": {
"title": "$:/core/modules/filters/is/image.js",
"text": "/*\\\ntitle: $:/core/modules/filters/is/image.js\ntype: application/javascript\nmodule-type: isfilteroperator\n\nFilter function for [is[image]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.image = function(source,prefix,options) {\n\tvar results = [];\n\tif(prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(!options.wiki.isImageTiddler(title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(options.wiki.isImageTiddler(title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "isfilteroperator"
},
"$:/core/modules/filters/is/missing.js": {
"title": "$:/core/modules/filters/is/missing.js",
"text": "/*\\\ntitle: $:/core/modules/filters/is/missing.js\ntype: application/javascript\nmodule-type: isfilteroperator\n\nFilter function for [is[missing]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.missing = function(source,prefix,options) {\n\tvar results = [];\n\tif(prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(options.wiki.tiddlerExists(title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(!options.wiki.tiddlerExists(title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "isfilteroperator"
},
"$:/core/modules/filters/is/orphan.js": {
"title": "$:/core/modules/filters/is/orphan.js",
"text": "/*\\\ntitle: $:/core/modules/filters/is/orphan.js\ntype: application/javascript\nmodule-type: isfilteroperator\n\nFilter function for [is[orphan]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.orphan = function(source,prefix,options) {\n\tvar results = [],\n\t\torphanTitles = options.wiki.getOrphanTitles();\n\tif(prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(orphanTitles.indexOf(title) === -1) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(orphanTitles.indexOf(title) !== -1) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "isfilteroperator"
},
"$:/core/modules/filters/is/shadow.js": {
"title": "$:/core/modules/filters/is/shadow.js",
"text": "/*\\\ntitle: $:/core/modules/filters/is/shadow.js\ntype: application/javascript\nmodule-type: isfilteroperator\n\nFilter function for [is[shadow]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.shadow = function(source,prefix,options) {\n\tvar results = [];\n\tif(prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(!options.wiki.isShadowTiddler(title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(options.wiki.isShadowTiddler(title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "isfilteroperator"
},
"$:/core/modules/filters/is/system.js": {
"title": "$:/core/modules/filters/is/system.js",
"text": "/*\\\ntitle: $:/core/modules/filters/is/system.js\ntype: application/javascript\nmodule-type: isfilteroperator\n\nFilter function for [is[system]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.system = function(source,prefix,options) {\n\tvar results = [];\n\tif(prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(!options.wiki.isSystemTiddler(title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(options.wiki.isSystemTiddler(title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "isfilteroperator"
},
"$:/core/modules/filters/is/tag.js": {
"title": "$:/core/modules/filters/is/tag.js",
"text": "/*\\\ntitle: $:/core/modules/filters/is/tag.js\ntype: application/javascript\nmodule-type: isfilteroperator\n\nFilter function for [is[tag]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.tag = function(source,prefix,options) {\n\tvar results = [],\n\t\ttagMap = options.wiki.getTagMap();\n\tif(prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(!$tw.utils.hop(tagMap,title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif($tw.utils.hop(tagMap,title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "isfilteroperator"
},
"$:/core/modules/filters/is/tiddler.js": {
"title": "$:/core/modules/filters/is/tiddler.js",
"text": "/*\\\ntitle: $:/core/modules/filters/is/tiddler.js\ntype: application/javascript\nmodule-type: isfilteroperator\n\nFilter function for [is[tiddler]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.tiddler = function(source,prefix,options) {\n\tvar results = [];\n\tif(prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(!options.wiki.tiddlerExists(title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(options.wiki.tiddlerExists(title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "isfilteroperator"
},
"$:/core/modules/filters/is.js": {
"title": "$:/core/modules/filters/is.js",
"text": "/*\\\ntitle: $:/core/modules/filters/is.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for checking tiddler properties\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar isFilterOperators;\n\nfunction getIsFilterOperators() {\n\tif(!isFilterOperators) {\n\t\tisFilterOperators = {};\n\t\t$tw.modules.applyMethods(\"isfilteroperator\",isFilterOperators);\n\t}\n\treturn isFilterOperators;\n}\n\n/*\nExport our filter function\n*/\nexports.is = function(source,operator,options) {\n\t// Dispatch to the correct isfilteroperator\n\tvar isFilterOperators = getIsFilterOperators();\n\tif(operator.operand) {\n\t\tvar isFilterOperator = isFilterOperators[operator.operand];\n\t\tif(isFilterOperator) {\n\t\t\treturn isFilterOperator(source,operator.prefix,options);\n\t\t} else {\n\t\t\treturn [$tw.language.getString(\"Error/IsFilterOperator\")];\n\t\t}\n\t} else {\n\t\t// Return all tiddlers if the operand is missing\n\t\tvar results = [];\n\t\tsource(function(tiddler,title) {\n\t\t\tresults.push(title);\n\t\t});\n\t\treturn results;\n\t}\n};\n\n})();",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/limit.js": {
"title": "$:/core/modules/filters/limit.js",
"text": "/*\\\ntitle: $:/core/modules/filters/limit.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for chopping the results to a specified maximum number of entries\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.limit = function(source,operator,options) {\n\tvar results = [];\n\t// Convert to an array\n\tsource(function(tiddler,title) {\n\t\tresults.push(title);\n\t});\n\t// Slice the array if necessary\n\tvar limit = Math.min(results.length,parseInt(operator.operand,10));\n\tif(operator.prefix === \"!\") {\n\t\tresults = results.slice(-limit);\n\t} else {\n\t\tresults = results.slice(0,limit);\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/links.js": {
"title": "$:/core/modules/filters/links.js",
"text": "/*\\\ntitle: $:/core/modules/filters/links.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning all the links from a tiddler\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.links = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\t$tw.utils.pushTop(results,options.wiki.getTiddlerLinks(title));\n\t});\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/list.js": {
"title": "$:/core/modules/filters/list.js",
"text": "/*\\\ntitle: $:/core/modules/filters/list.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning the tiddlers whose title is listed in the operand tiddler\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.list = function(source,operator,options) {\n\tvar results = [],\n\t\ttr = $tw.utils.parseTextReference(operator.operand),\n\t\tcurrTiddlerTitle = options.widget && options.widget.getVariable(\"currentTiddler\"),\n\t\tlist = options.wiki.getTiddlerList(tr.title || currTiddlerTitle,tr.field,tr.index);\n\tif(operator.prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(list.indexOf(title) === -1) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tresults = list;\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/listed.js": {
"title": "$:/core/modules/filters/listed.js",
"text": "/*\\\ntitle: $:/core/modules/filters/listed.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning all tiddlers that have the selected tiddlers in a list\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.listed = function(source,operator,options) {\n\tvar field = operator.operand || \"list\",\n\t\tresults = [];\n\tsource(function(tiddler,title) {\n\t\t$tw.utils.pushTop(results,options.wiki.findListingsOfTiddler(title,field));\n\t});\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/listops.js": {
"title": "$:/core/modules/filters/listops.js",
"text": "/*\\\ntitle: $:/core/modules/filters/listops.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operators for manipulating the current selection list\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nOrder a list\n*/\nexports.order = function(source,operator,options) {\n\tvar results = [];\n\tif(operator.operand.toLowerCase() === \"reverse\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tresults.unshift(title);\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tresults.push(title);\n\t\t});\n\t}\n\treturn results;\n};\n\n/*\nReverse list\n*/\nexports.reverse = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.unshift(title);\n\t});\n\treturn results;\n};\n\n/*\nFirst entry/entries in list\n*/\nexports.first = function(source,operator,options) {\n\tvar count = $tw.utils.getInt(operator.operand,1),\n\t\tresults = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(title);\n\t});\n\treturn results.slice(0,count);\n};\n\n/*\nLast entry/entries in list\n*/\nexports.last = function(source,operator,options) {\n\tvar count = $tw.utils.getInt(operator.operand,1),\n\t\tresults = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(title);\n\t});\n\treturn results.slice(-count);\n};\n\n/*\nAll but the first entry/entries of the list\n*/\nexports.rest = function(source,operator,options) {\n\tvar count = $tw.utils.getInt(operator.operand,1),\n\t\tresults = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(title);\n\t});\n\treturn results.slice(count);\n};\nexports.butfirst = exports.rest;\nexports.bf = exports.rest;\n\n/*\nAll but the last entry/entries of the list\n*/\nexports.butlast = function(source,operator,options) {\n\tvar count = $tw.utils.getInt(operator.operand,1),\n\t\tresults = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(title);\n\t});\n\treturn results.slice(0,-count);\n};\nexports.bl = exports.butlast;\n\n/*\nThe nth member of the list\n*/\nexports.nth = function(source,operator,options) {\n\tvar count = $tw.utils.getInt(operator.operand,1),\n\t\tresults = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(title);\n\t});\n\treturn results.slice(count - 1,count);\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/lookup.js": {
"title": "$:/core/modules/filters/lookup.js",
"text": "/*\\\ntitle: $:/core/modules/filters/lookup.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator that looks up values via a title prefix\n\n[lookup:<field>[<prefix>]]\n\nPrepends the prefix to the selected items and returns the specified field value\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.lookup = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(options.wiki.getTiddlerText(operator.operand + title) || options.wiki.getTiddlerText(operator.operand + operator.suffix));\n\t});\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/minlength.js": {
"title": "$:/core/modules/filters/minlength.js",
"text": "/*\\\ntitle: $:/core/modules/filters/minlength.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for filtering out titles that don't meet the minimum length in the operand\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.minlength = function(source,operator,options) {\n\tvar results = [],\n\t\tminLength = parseInt(operator.operand || \"\",10) || 0;\n\tsource(function(tiddler,title) {\n\t\tif(title.length >= minLength) {\n\t\t\tresults.push(title);\n\t\t}\n\t});\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/modules.js": {
"title": "$:/core/modules/filters/modules.js",
"text": "/*\\\ntitle: $:/core/modules/filters/modules.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the titles of the modules of a given type in this wiki\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.modules = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\t$tw.utils.each($tw.modules.types[title],function(moduleInfo,moduleName) {\n\t\t\tresults.push(moduleName);\n\t\t});\n\t});\n\tresults.sort();\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/moduletypes.js": {
"title": "$:/core/modules/filters/moduletypes.js",
"text": "/*\\\ntitle: $:/core/modules/filters/moduletypes.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the names of the module types in this wiki\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.moduletypes = function(source,operator,options) {\n\tvar results = [];\n\t$tw.utils.each($tw.modules.types,function(moduleInfo,type) {\n\t\tresults.push(type);\n\t});\n\tresults.sort();\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/next.js": {
"title": "$:/core/modules/filters/next.js",
"text": "/*\\\ntitle: $:/core/modules/filters/next.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning the tiddler whose title occurs next in the list supplied in the operand tiddler\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.next = function(source,operator,options) {\n\tvar results = [],\n\t\tlist = options.wiki.getTiddlerList(operator.operand);\n\tsource(function(tiddler,title) {\n\t\tvar match = list.indexOf(title);\n\t\t// increment match and then test if result is in range\n\t\tmatch++;\n\t\tif(match > 0 && match < list.length) {\n\t\t\tresults.push(list[match]);\n\t\t}\n\t});\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/plugintiddlers.js": {
"title": "$:/core/modules/filters/plugintiddlers.js",
"text": "/*\\\ntitle: $:/core/modules/filters/plugintiddlers.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the titles of the shadow tiddlers within a plugin\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.plugintiddlers = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tvar pluginInfo = options.wiki.getPluginInfo(title) || options.wiki.getTiddlerDataCached(title,{tiddlers:[]});\n\t\tif(pluginInfo && pluginInfo.tiddlers) {\n\t\t\t$tw.utils.each(pluginInfo.tiddlers,function(fields,title) {\n\t\t\t\tresults.push(title);\n\t\t\t});\n\t\t}\n\t});\n\tresults.sort();\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/prefix.js": {
"title": "$:/core/modules/filters/prefix.js",
"text": "/*\\\ntitle: $:/core/modules/filters/prefix.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for checking if a title starts with a prefix\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.prefix = function(source,operator,options) {\n\tvar results = [];\n\tif(operator.prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(title.substr(0,operator.operand.length) !== operator.operand) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(title.substr(0,operator.operand.length) === operator.operand) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/previous.js": {
"title": "$:/core/modules/filters/previous.js",
"text": "/*\\\ntitle: $:/core/modules/filters/previous.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning the tiddler whose title occurs immediately prior in the list supplied in the operand tiddler\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.previous = function(source,operator,options) {\n\tvar results = [],\n\t\tlist = options.wiki.getTiddlerList(operator.operand);\n\tsource(function(tiddler,title) {\n\t\tvar match = list.indexOf(title);\n\t\t// increment match and then test if result is in range\n\t\tmatch--;\n\t\tif(match >= 0) {\n\t\t\tresults.push(list[match]);\n\t\t}\n\t});\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/range.js": {
"title": "$:/core/modules/filters/range.js",
"text": "/*\\\ntitle: $:/core/modules/filters/range.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for generating a numeric range.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.range = function(source,operator,options) {\n\tvar results = [];\n\t// Split the operand into numbers delimited by these symbols\n\tvar parts = operator.operand.split(/[,:;]/g),\n\t\tbeg, end, inc, i, fixed = 0;\n\tfor (i=0; i<parts.length; i++) {\n\t\t// Validate real number\n\t\tif(!/^\\s*[+-]?((\\d+(\\.\\d*)?)|(\\.\\d+))\\s*$/.test(parts[i])) {\n\t\t\treturn [\"range: bad number \\\"\" + parts[i] + \"\\\"\"];\n\t\t}\n\t\t// Count digits; the most precise number determines decimal places in output.\n\t\tvar frac = /\\.\\d+/.exec(parts[i]);\n\t\tif(frac) {\n\t\t\tfixed = Math.max(fixed,frac[0].length-1);\n\t\t}\n\t\tparts[i] = parseFloat(parts[i]);\n\t}\n\tswitch(parts.length) {\n\t\tcase 1:\n\t\t\tend = parts[0];\n\t\t\tif (end >= 1) {\n\t\t\t\tbeg = 1;\n\t\t\t}\n\t\t\telse if (end <= -1) {\n\t\t\t\tbeg = -1;\n\t\t\t}\n\t\t\telse {\n\t\t\t\treturn [];\n\t\t\t}\n\t\t\tinc = 1;\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tbeg = parts[0];\n\t\t\tend = parts[1];\n\t\t\tinc = 1;\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\tbeg = parts[0];\n\t\t\tend = parts[1];\n\t\t\tinc = Math.abs(parts[2]);\n\t\t\tbreak;\n\t}\n\tif(inc === 0) {\n\t\treturn [\"range: increment 0 causes infinite loop\"];\n\t}\n\t// May need to count backwards\n\tvar direction = ((end < beg) ? -1 : 1);\n\tinc *= direction;\n\t// Estimate number of resulting elements\n\tif((end - beg) / inc > 10000) {\n\t\treturn [\"range: too many steps (over 10K)\"];\n\t}\n\t// Avoid rounding error on last step\n\tend += direction * 0.5 * Math.pow(0.1,fixed);\n\tvar safety = 10010;\n\t// Enumerate the range\n\tif (end<beg) {\n\t\tfor(i=beg; i>end; i+=inc) {\n\t\t\tresults.push(i.toFixed(fixed));\n\t\t\tif(--safety<0) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t} else {\n\t\tfor(i=beg; i<end; i+=inc) {\n\t\t\tresults.push(i.toFixed(fixed));\n\t\t\tif(--safety<0) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\tif(safety<0) {\n\t\treturn [\"range: unexpectedly large output\"];\n\t}\n\t// Reverse?\n\tif(operator.prefix === \"!\") {\n\t\tresults.reverse();\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/regexp.js": {
"title": "$:/core/modules/filters/regexp.js",
"text": "/*\\\ntitle: $:/core/modules/filters/regexp.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for regexp matching\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.regexp = function(source,operator,options) {\n\tvar results = [],\n\t\tfieldname = (operator.suffix || \"title\").toLowerCase(),\n\t\tregexpString, regexp, flags = \"\", match,\n\t\tgetFieldString = function(tiddler,title) {\n\t\t\tif(tiddler) {\n\t\t\t\treturn tiddler.getFieldString(fieldname);\n\t\t\t} else if(fieldname === \"title\") {\n\t\t\t\treturn title;\n\t\t\t} else {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t};\n\t// Process flags and construct regexp\n\tregexpString = operator.operand;\n\tmatch = /^\\(\\?([gim]+)\\)/.exec(regexpString);\n\tif(match) {\n\t\tflags = match[1];\n\t\tregexpString = regexpString.substr(match[0].length);\n\t} else {\n\t\tmatch = /\\(\\?([gim]+)\\)$/.exec(regexpString);\n\t\tif(match) {\n\t\t\tflags = match[1];\n\t\t\tregexpString = regexpString.substr(0,regexpString.length - match[0].length);\n\t\t}\n\t}\n\ttry {\n\t\tregexp = new RegExp(regexpString,flags);\n\t} catch(e) {\n\t\treturn [\"\" + e];\n\t}\n\t// Process the incoming tiddlers\n\tif(operator.prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tvar text = getFieldString(tiddler,title);\n\t\t\tif(text !== null) {\n\t\t\t\tif(!regexp.exec(text)) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tvar text = getFieldString(tiddler,title);\n\t\t\tif(text !== null) {\n\t\t\t\tif(!!regexp.exec(text)) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/removeprefix.js": {
"title": "$:/core/modules/filters/removeprefix.js",
"text": "/*\\\ntitle: $:/core/modules/filters/removeprefix.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for removing a prefix from each title in the list. Titles that do not start with the prefix are removed.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.removeprefix = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tif(title.substr(0,operator.operand.length) === operator.operand) {\n\t\t\tresults.push(title.substr(operator.operand.length));\n\t\t}\n\t});\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/removesuffix.js": {
"title": "$:/core/modules/filters/removesuffix.js",
"text": "/*\\\ntitle: $:/core/modules/filters/removesuffix.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for removing a suffix from each title in the list. Titles that do not end with the suffix are removed.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.removesuffix = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tif(title.substr(-operator.operand.length) === operator.operand) {\n\t\t\tresults.push(title.substr(0,title.length - operator.operand.length));\n\t\t}\n\t});\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/sameday.js": {
"title": "$:/core/modules/filters/sameday.js",
"text": "/*\\\ntitle: $:/core/modules/filters/sameday.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator that selects tiddlers with a modified date field on the same day as the provided value.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.sameday = function(source,operator,options) {\n\tvar results = [],\n\t\tfieldName = operator.suffix || \"modified\",\n\t\ttargetDate = (new Date($tw.utils.parseDate(operator.operand))).setHours(0,0,0,0);\n\t// Function to convert a date/time to a date integer\n\tsource(function(tiddler,title) {\n\t\tif(tiddler) {\n\t\t\tif(tiddler.getFieldDay(fieldName) === targetDate) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t}\n\t});\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/search.js": {
"title": "$:/core/modules/filters/search.js",
"text": "/*\\\ntitle: $:/core/modules/filters/search.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for searching for the text in the operand tiddler\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.search = function(source,operator,options) {\n\tvar invert = operator.prefix === \"!\";\n\tif(operator.suffixes) {\n\t\tvar hasFlag = function(flag) {\n\t\t\t\treturn (operator.suffixes[1] || []).indexOf(flag) !== -1;\n\t\t\t},\n\t\t\texcludeFields = false,\n\t\t\tfieldList = operator.suffixes[0] || [],\n\t\t\tfirstField = fieldList[0] || \"\", \n\t\t\tfirstChar = firstField.charAt(0),\n\t\t\tfields;\n\t\tif(firstChar === \"-\") {\n\t\t\tfields = [firstField.slice(1)].concat(fieldList.slice(1));\n\t\t\texcludeFields = true;\n\t\t} else if(fieldList[0] === \"*\"){\n\t\t\tfields = [];\n\t\t\texcludeFields = true;\n\t\t} else {\n\t\t\tfields = fieldList.slice(0);\n\t\t}\n\t\treturn options.wiki.search(operator.operand,{\n\t\t\tsource: source,\n\t\t\tinvert: invert,\n\t\t\tfield: fields,\n\t\t\texcludeField: excludeFields,\n\t\t\tcaseSensitive: hasFlag(\"casesensitive\"),\n\t\t\tliteral: hasFlag(\"literal\"),\n\t\t\twhitespace: hasFlag(\"whitespace\"),\n\t\t\tregexp: hasFlag(\"regexp\"),\n\t\t\twords: hasFlag(\"words\")\n\t\t});\n\t} else {\n\t\treturn options.wiki.search(operator.operand,{\n\t\t\tsource: source,\n\t\t\tinvert: invert\n\t\t});\n\t}\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/shadowsource.js": {
"title": "$:/core/modules/filters/shadowsource.js",
"text": "/*\\\ntitle: $:/core/modules/filters/shadowsource.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the source plugins for shadow tiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.shadowsource = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tvar source = options.wiki.getShadowSource(title);\n\t\tif(source) {\n\t\t\t$tw.utils.pushTop(results,source);\n\t\t}\n\t});\n\tresults.sort();\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/sort.js": {
"title": "$:/core/modules/filters/sort.js",
"text": "/*\\\ntitle: $:/core/modules/filters/sort.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for sorting\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.sort = function(source,operator,options) {\n\tvar results = prepare_results(source);\n\toptions.wiki.sortTiddlers(results,operator.operand || \"title\",operator.prefix === \"!\",false,false);\n\treturn results;\n};\n\nexports.nsort = function(source,operator,options) {\n\tvar results = prepare_results(source);\n\toptions.wiki.sortTiddlers(results,operator.operand || \"title\",operator.prefix === \"!\",false,true);\n\treturn results;\n};\n\nexports.sortan = function(source, operator, options) {\n\tvar results = prepare_results(source);\n\toptions.wiki.sortTiddlers(results, operator.operand || \"title\", operator.prefix === \"!\",false,false,true);\n\treturn results;\n};\n\nexports.sortcs = function(source,operator,options) {\n\tvar results = prepare_results(source);\n\toptions.wiki.sortTiddlers(results,operator.operand || \"title\",operator.prefix === \"!\",true,false);\n\treturn results;\n};\n\nexports.nsortcs = function(source,operator,options) {\n\tvar results = prepare_results(source);\n\toptions.wiki.sortTiddlers(results,operator.operand || \"title\",operator.prefix === \"!\",true,true);\n\treturn results;\n};\n\nvar prepare_results = function (source) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(title);\n\t});\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/splitbefore.js": {
"title": "$:/core/modules/filters/splitbefore.js",
"text": "/*\\\ntitle: $:/core/modules/filters/splitbefore.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator that splits each result on the first occurance of the specified separator and returns the unique values.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.splitbefore = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tvar parts = title.split(operator.operand);\n\t\tif(parts.length === 1) {\n\t\t\t$tw.utils.pushTop(results,parts[0]);\n\t\t} else {\n\t\t\t$tw.utils.pushTop(results,parts[0] + operator.operand);\n\t\t}\n\t});\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/storyviews.js": {
"title": "$:/core/modules/filters/storyviews.js",
"text": "/*\\\ntitle: $:/core/modules/filters/storyviews.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the names of the story views in this wiki\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.storyviews = function(source,operator,options) {\n\tvar results = [],\n\t\tstoryviews = {};\n\t$tw.modules.applyMethods(\"storyview\",storyviews);\n\t$tw.utils.each(storyviews,function(info,name) {\n\t\tresults.push(name);\n\t});\n\tresults.sort();\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/subfilter.js": {
"title": "$:/core/modules/filters/subfilter.js",
"text": "/*\\\ntitle: $:/core/modules/filters/subfilter.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning its operand evaluated as a filter\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.subfilter = function(source,operator,options) {\n\tvar list = options.wiki.filterTiddlers(operator.operand,options.widget,source);\n\tif(operator.prefix === \"!\") {\n\t\tvar results = [];\n\t\tsource(function(tiddler,title) {\n\t\t\tif(list.indexOf(title) === -1) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t\treturn results;\n\t} else {\n\t\treturn list;\n\t}\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/subtiddlerfields.js": {
"title": "$:/core/modules/filters/subtiddlerfields.js",
"text": "/*\\\ntitle: $:/core/modules/filters/subtiddlerfields.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the names of the fields on the selected subtiddlers of the plugin named in the operand\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.subtiddlerfields = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tvar subtiddler = options.wiki.getSubTiddler(operator.operand,title);\n\t\tif(subtiddler) {\n\t\t\tfor(var fieldName in subtiddler.fields) {\n\t\t\t\t$tw.utils.pushTop(results,fieldName);\n\t\t\t}\n\t\t}\n\t});\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/suffix.js": {
"title": "$:/core/modules/filters/suffix.js",
"text": "/*\\\ntitle: $:/core/modules/filters/suffix.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for checking if a title ends with a suffix\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.suffix = function(source,operator,options) {\n\tvar results = [];\n\tif(operator.prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(title.substr(-operator.operand.length) !== operator.operand) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(title.substr(-operator.operand.length) === operator.operand) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/tag.js": {
"title": "$:/core/modules/filters/tag.js",
"text": "/*\\\ntitle: $:/core/modules/filters/tag.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for checking for the presence of a tag\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.tag = function(source,operator,options) {\n\tvar results = [];\n\tif((operator.suffix || \"\").toLowerCase() === \"strict\" && !operator.operand) {\n\t\t// New semantics:\n\t\t// Always return copy of input if operator.operand is missing\n\t\tsource(function(tiddler,title) {\n\t\t\tresults.push(title);\n\t\t});\n\t} else {\n\t\t// Old semantics:\n\t\tvar tiddlers = options.wiki.getTiddlersWithTag(operator.operand);\n\t\tif(operator.prefix === \"!\") {\n\t\t\t// Returns a copy of the input if operator.operand is missing\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(tiddlers.indexOf(title) === -1) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\t// Returns empty results if operator.operand is missing\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(tiddlers.indexOf(title) !== -1) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t\tresults = options.wiki.sortByList(results,operator.operand);\n\t\t}\t\t\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/tagging.js": {
"title": "$:/core/modules/filters/tagging.js",
"text": "/*\\\ntitle: $:/core/modules/filters/tagging.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning all tiddlers that are tagged with the selected tiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.tagging = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\t$tw.utils.pushTop(results,options.wiki.getTiddlersWithTag(title));\n\t});\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/tags.js": {
"title": "$:/core/modules/filters/tags.js",
"text": "/*\\\ntitle: $:/core/modules/filters/tags.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning all the tags of the selected tiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.tags = function(source,operator,options) {\n\tvar tags = {};\n\tsource(function(tiddler,title) {\n\t\tvar t, length;\n\t\tif(tiddler && tiddler.fields.tags) {\n\t\t\tfor(t=0, length=tiddler.fields.tags.length; t<length; t++) {\n\t\t\t\ttags[tiddler.fields.tags[t]] = true;\n\t\t\t}\n\t\t}\n\t});\n\treturn Object.keys(tags);\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/title.js": {
"title": "$:/core/modules/filters/title.js",
"text": "/*\\\ntitle: $:/core/modules/filters/title.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for comparing title fields for equality\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.title = function(source,operator,options) {\n\tvar results = [];\n\tif(operator.prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(tiddler && tiddler.fields.title !== operator.operand) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tresults.push(operator.operand);\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/untagged.js": {
"title": "$:/core/modules/filters/untagged.js",
"text": "/*\\\ntitle: $:/core/modules/filters/untagged.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning all the selected tiddlers that are untagged\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.untagged = function(source,operator,options) {\n\tvar results = [];\n\tif(operator.prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(tiddler && $tw.utils.isArray(tiddler.fields.tags) && tiddler.fields.tags.length > 0) {\n\t\t\t\t$tw.utils.pushTop(results,title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(!tiddler || !tiddler.hasField(\"tags\") || ($tw.utils.isArray(tiddler.fields.tags) && tiddler.fields.tags.length === 0)) {\n\t\t\t\t$tw.utils.pushTop(results,title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/wikiparserrules.js": {
"title": "$:/core/modules/filters/wikiparserrules.js",
"text": "/*\\\ntitle: $:/core/modules/filters/wikiparserrules.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the names of the wiki parser rules in this wiki\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.wikiparserrules = function(source,operator,options) {\n\tvar results = [],\n\t\toperand = operator.operand;\n\t$tw.utils.each($tw.modules.types.wikirule,function(mod) {\n\t\tvar exp = mod.exports;\n\t\tif(!operand || exp.types[operand]) {\n\t\t\tresults.push(exp.name);\n\t\t}\n\t});\n\tresults.sort();\n\treturn results;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters/x-listops.js": {
"title": "$:/core/modules/filters/x-listops.js",
"text": "/*\\\ntitle: $:/core/modules/filters/x-listops.js\ntype: application/javascript\nmodule-type: filteroperator\n\nExtended filter operators to manipulate the current list.\n\n\\*/\n(function () {\n\n /*jslint node: true, browser: true */\n /*global $tw: false */\n \"use strict\";\n\n /*\n Fetch titles from the current list\n */\n var prepare_results = function (source) {\n var results = [];\n source(function (tiddler, title) {\n results.push(title);\n });\n return results;\n };\n\n /*\n Moves a number of items from the tail of the current list before the item named in the operand\n */\n exports.putbefore = function (source, operator) {\n var results = prepare_results(source),\n index = results.indexOf(operator.operand),\n count = $tw.utils.getInt(operator.suffix,1);\n return (index === -1) ?\n results.slice(0, -1) :\n results.slice(0, index).concat(results.slice(-count)).concat(results.slice(index, -count));\n };\n\n /*\n Moves a number of items from the tail of the current list after the item named in the operand\n */\n exports.putafter = function (source, operator) {\n var results = prepare_results(source),\n index = results.indexOf(operator.operand),\n count = $tw.utils.getInt(operator.suffix,1);\n return (index === -1) ?\n results.slice(0, -1) :\n results.slice(0, index + 1).concat(results.slice(-count)).concat(results.slice(index + 1, -count));\n };\n\n /*\n Replaces the item named in the operand with a number of items from the tail of the current list\n */\n exports.replace = function (source, operator) {\n var results = prepare_results(source),\n index = results.indexOf(operator.operand),\n count = $tw.utils.getInt(operator.suffix,1);\n return (index === -1) ?\n results.slice(0, -count) :\n results.slice(0, index).concat(results.slice(-count)).concat(results.slice(index + 1, -count));\n };\n\n /*\n Moves a number of items from the tail of the current list to the head of the list\n */\n exports.putfirst = function (source, operator) {\n var results = prepare_results(source),\n count = $tw.utils.getInt(operator.suffix,1);\n return results.slice(-count).concat(results.slice(0, -count));\n };\n\n /*\n Moves a number of items from the head of the current list to the tail of the list\n */\n exports.putlast = function (source, operator) {\n var results = prepare_results(source),\n count = $tw.utils.getInt(operator.suffix,1);\n return results.slice(count).concat(results.slice(0, count));\n };\n\n /*\n Moves the item named in the operand a number of places forward or backward in the list\n */\n exports.move = function (source, operator) {\n var results = prepare_results(source),\n index = results.indexOf(operator.operand),\n count = $tw.utils.getInt(operator.suffix,1),\n marker = results.splice(index, 1),\n offset = (index + count) > 0 ? index + count : 0;\n return results.slice(0, offset).concat(marker).concat(results.slice(offset));\n };\n\n /*\n Returns the items from the current list that are after the item named in the operand\n */\n exports.allafter = function (source, operator) {\n var results = prepare_results(source),\n index = results.indexOf(operator.operand);\n return (index === -1 || index > (results.length - 2)) ? [] :\n (operator.suffix) ? results.slice(index) :\n results.slice(index + 1);\n };\n\n /*\n Returns the items from the current list that are before the item named in the operand\n */\n exports.allbefore = function (source, operator) {\n var results = prepare_results(source),\n index = results.indexOf(operator.operand);\n return (index < 0) ? [] :\n (operator.suffix) ? results.slice(0, index + 1) :\n results.slice(0, index);\n };\n\n /*\n Appends the items listed in the operand array to the tail of the current list\n */\n exports.append = function (source, operator) {\n var append = $tw.utils.parseStringArray(operator.operand, \"true\"),\n results = prepare_results(source),\n count = parseInt(operator.suffix) || append.length;\n return (append.length === 0) ? results :\n (operator.prefix) ? results.concat(append.slice(-count)) :\n results.concat(append.slice(0, count));\n };\n\n /*\n Prepends the items listed in the operand array to the head of the current list\n */\n exports.prepend = function (source, operator) {\n var prepend = $tw.utils.parseStringArray(operator.operand, \"true\"),\n results = prepare_results(source),\n count = $tw.utils.getInt(operator.suffix,prepend.length);\n return (prepend.length === 0) ? results :\n (operator.prefix) ? prepend.slice(-count).concat(results) :\n prepend.slice(0, count).concat(results);\n };\n\n /*\n Returns all items from the current list except the items listed in the operand array\n */\n exports.remove = function (source, operator) {\n var array = $tw.utils.parseStringArray(operator.operand, \"true\"),\n results = prepare_results(source),\n count = parseInt(operator.suffix) || array.length,\n p,\n len,\n index;\n len = array.length - 1;\n for (p = 0; p < count; ++p) {\n if (operator.prefix) {\n index = results.indexOf(array[len - p]);\n } else {\n index = results.indexOf(array[p]);\n }\n if (index !== -1) {\n results.splice(index, 1);\n }\n }\n return results;\n };\n\n /*\n Returns all items from the current list sorted in the order of the items in the operand array\n */\n exports.sortby = function (source, operator) {\n var results = prepare_results(source);\n if (!results || results.length < 2) {\n return results;\n }\n var lookup = $tw.utils.parseStringArray(operator.operand, \"true\");\n results.sort(function (a, b) {\n return lookup.indexOf(a) - lookup.indexOf(b);\n });\n return results;\n };\n\n /*\n Removes all duplicate items from the current list\n */\n exports.unique = function (source, operator) {\n var results = prepare_results(source);\n var set = results.reduce(function (a, b) {\n if (a.indexOf(b) < 0) {\n a.push(b);\n }\n return a;\n }, []);\n return set;\n };\n})();\n",
"type": "application/javascript",
"module-type": "filteroperator"
},
"$:/core/modules/filters.js": {
"title": "$:/core/modules/filters.js",
"text": "/*\\\ntitle: $:/core/modules/filters.js\ntype: application/javascript\nmodule-type: wikimethod\n\nAdds tiddler filtering methods to the $tw.Wiki object.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nParses an operation (i.e. a run) within a filter string\n\toperators: Array of array of operator nodes into which results should be inserted\n\tfilterString: filter string\n\tp: start position within the string\nReturns the new start position, after the parsed operation\n*/\nfunction parseFilterOperation(operators,filterString,p) {\n\tvar nextBracketPos, operator;\n\t// Skip the starting square bracket\n\tif(filterString.charAt(p++) !== \"[\") {\n\t\tthrow \"Missing [ in filter expression\";\n\t}\n\t// Process each operator in turn\n\tdo {\n\t\toperator = {};\n\t\t// Check for an operator prefix\n\t\tif(filterString.charAt(p) === \"!\") {\n\t\t\toperator.prefix = filterString.charAt(p++);\n\t\t}\n\t\t// Get the operator name\n\t\tnextBracketPos = filterString.substring(p).search(/[\\[\\{<\\/]/);\n\t\tif(nextBracketPos === -1) {\n\t\t\tthrow \"Missing [ in filter expression\";\n\t\t}\n\t\tnextBracketPos += p;\n\t\tvar bracket = filterString.charAt(nextBracketPos);\n\t\toperator.operator = filterString.substring(p,nextBracketPos);\n\t\t// Any suffix?\n\t\tvar colon = operator.operator.indexOf(':');\n\t\tif(colon > -1) {\n\t\t\t// The raw suffix for older filters\n\t\t\toperator.suffix = operator.operator.substring(colon + 1);\n\t\t\toperator.operator = operator.operator.substring(0,colon) || \"field\";\n\t\t\t// The processed suffix for newer filters\n\t\t\toperator.suffixes = [];\n\t\t\t$tw.utils.each(operator.suffix.split(\":\"),function(subsuffix) {\n\t\t\t\toperator.suffixes.push([]);\n\t\t\t\t$tw.utils.each(subsuffix.split(\",\"),function(entry) {\n\t\t\t\t\tentry = $tw.utils.trim(entry);\n\t\t\t\t\tif(entry) {\n\t\t\t\t\t\toperator.suffixes[operator.suffixes.length - 1].push(entry); \n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t});\n\t\t}\n\t\t// Empty operator means: title\n\t\telse if(operator.operator === \"\") {\n\t\t\toperator.operator = \"title\";\n\t\t}\n\n\t\tp = nextBracketPos + 1;\n\t\tswitch (bracket) {\n\t\t\tcase \"{\": // Curly brackets\n\t\t\t\toperator.indirect = true;\n\t\t\t\tnextBracketPos = filterString.indexOf(\"}\",p);\n\t\t\t\tbreak;\n\t\t\tcase \"[\": // Square brackets\n\t\t\t\tnextBracketPos = filterString.indexOf(\"]\",p);\n\t\t\t\tbreak;\n\t\t\tcase \"<\": // Angle brackets\n\t\t\t\toperator.variable = true;\n\t\t\t\tnextBracketPos = filterString.indexOf(\">\",p);\n\t\t\t\tbreak;\n\t\t\tcase \"/\": // regexp brackets\n\t\t\t\tvar rex = /^((?:[^\\\\\\/]*|\\\\.)*)\\/(?:\\(([mygi]+)\\))?/g,\n\t\t\t\t\trexMatch = rex.exec(filterString.substring(p));\n\t\t\t\tif(rexMatch) {\n\t\t\t\t\toperator.regexp = new RegExp(rexMatch[1], rexMatch[2]);\n// DEPRECATION WARNING\nconsole.log(\"WARNING: Filter\",operator.operator,\"has a deprecated regexp operand\",operator.regexp);\n\t\t\t\t\tnextBracketPos = p + rex.lastIndex - 1;\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tthrow \"Unterminated regular expression in filter expression\";\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\n\t\tif(nextBracketPos === -1) {\n\t\t\tthrow \"Missing closing bracket in filter expression\";\n\t\t}\n\t\tif(!operator.regexp) {\n\t\t\toperator.operand = filterString.substring(p,nextBracketPos);\n\t\t}\n\t\tp = nextBracketPos + 1;\n\n\t\t// Push this operator\n\t\toperators.push(operator);\n\t} while(filterString.charAt(p) !== \"]\");\n\t// Skip the ending square bracket\n\tif(filterString.charAt(p++) !== \"]\") {\n\t\tthrow \"Missing ] in filter expression\";\n\t}\n\t// Return the parsing position\n\treturn p;\n}\n\n/*\nParse a filter string\n*/\nexports.parseFilter = function(filterString) {\n\tfilterString = filterString || \"\";\n\tvar results = [], // Array of arrays of operator nodes {operator:,operand:}\n\t\tp = 0, // Current position in the filter string\n\t\tmatch;\n\tvar whitespaceRegExp = /(\\s+)/mg,\n\t\toperandRegExp = /((?:\\+|\\-|~)?)(?:(\\[)|(?:\"([^\"]*)\")|(?:'([^']*)')|([^\\s\\[\\]]+))/mg;\n\twhile(p < filterString.length) {\n\t\t// Skip any whitespace\n\t\twhitespaceRegExp.lastIndex = p;\n\t\tmatch = whitespaceRegExp.exec(filterString);\n\t\tif(match && match.index === p) {\n\t\t\tp = p + match[0].length;\n\t\t}\n\t\t// Match the start of the operation\n\t\tif(p < filterString.length) {\n\t\t\toperandRegExp.lastIndex = p;\n\t\t\tmatch = operandRegExp.exec(filterString);\n\t\t\tif(!match || match.index !== p) {\n\t\t\t\tthrow $tw.language.getString(\"Error/FilterSyntax\");\n\t\t\t}\n\t\t\tvar operation = {\n\t\t\t\tprefix: \"\",\n\t\t\t\toperators: []\n\t\t\t};\n\t\t\tif(match[1]) {\n\t\t\t\toperation.prefix = match[1];\n\t\t\t\tp++;\n\t\t\t}\n\t\t\tif(match[2]) { // Opening square bracket\n\t\t\t\tp = parseFilterOperation(operation.operators,filterString,p);\n\t\t\t} else {\n\t\t\t\tp = match.index + match[0].length;\n\t\t\t}\n\t\t\tif(match[3] || match[4] || match[5]) { // Double quoted string, single quoted string or unquoted title\n\t\t\t\toperation.operators.push(\n\t\t\t\t\t{operator: \"title\", operand: match[3] || match[4] || match[5]}\n\t\t\t\t);\n\t\t\t}\n\t\t\tresults.push(operation);\n\t\t}\n\t}\n\treturn results;\n};\n\nexports.getFilterOperators = function() {\n\tif(!this.filterOperators) {\n\t\t$tw.Wiki.prototype.filterOperators = {};\n\t\t$tw.modules.applyMethods(\"filteroperator\",this.filterOperators);\n\t}\n\treturn this.filterOperators;\n};\n\nexports.filterTiddlers = function(filterString,widget,source) {\n\tvar fn = this.compileFilter(filterString);\n\treturn fn.call(this,source,widget);\n};\n\n/*\nCompile a filter into a function with the signature fn(source,widget) where:\nsource: an iterator function for the source tiddlers, called source(iterator), where iterator is called as iterator(tiddler,title)\nwidget: an optional widget node for retrieving the current tiddler etc.\n*/\nexports.compileFilter = function(filterString) {\n\tvar filterParseTree;\n\ttry {\n\t\tfilterParseTree = this.parseFilter(filterString);\n\t} catch(e) {\n\t\treturn function(source,widget) {\n\t\t\treturn [$tw.language.getString(\"Error/Filter\") + \": \" + e];\n\t\t};\n\t}\n\t// Get the hashmap of filter operator functions\n\tvar filterOperators = this.getFilterOperators();\n\t// Assemble array of functions, one for each operation\n\tvar operationFunctions = [];\n\t// Step through the operations\n\tvar self = this;\n\t$tw.utils.each(filterParseTree,function(operation) {\n\t\t// Create a function for the chain of operators in the operation\n\t\tvar operationSubFunction = function(source,widget) {\n\t\t\tvar accumulator = source,\n\t\t\t\tresults = [],\n\t\t\t\tcurrTiddlerTitle = widget && widget.getVariable(\"currentTiddler\");\n\t\t\t$tw.utils.each(operation.operators,function(operator) {\n\t\t\t\tvar operand = operator.operand,\n\t\t\t\t\toperatorFunction;\n\t\t\t\tif(!operator.operator) {\n\t\t\t\t\toperatorFunction = filterOperators.title;\n\t\t\t\t} else if(!filterOperators[operator.operator]) {\n\t\t\t\t\toperatorFunction = filterOperators.field;\n\t\t\t\t} else {\n\t\t\t\t\toperatorFunction = filterOperators[operator.operator];\n\t\t\t\t}\n\t\t\t\tif(operator.indirect) {\n\t\t\t\t\toperand = self.getTextReference(operator.operand,\"\",currTiddlerTitle);\n\t\t\t\t}\n\t\t\t\tif(operator.variable) {\n\t\t\t\t\toperand = widget.getVariable(operator.operand,{defaultValue: \"\"});\n\t\t\t\t}\n\t\t\t\t// Invoke the appropriate filteroperator module\n\t\t\t\tresults = operatorFunction(accumulator,{\n\t\t\t\t\t\t\toperator: operator.operator,\n\t\t\t\t\t\t\toperand: operand,\n\t\t\t\t\t\t\tprefix: operator.prefix,\n\t\t\t\t\t\t\tsuffix: operator.suffix,\n\t\t\t\t\t\t\tsuffixes: operator.suffixes,\n\t\t\t\t\t\t\tregexp: operator.regexp\n\t\t\t\t\t\t},{\n\t\t\t\t\t\t\twiki: self,\n\t\t\t\t\t\t\twidget: widget\n\t\t\t\t\t\t});\n\t\t\t\tif($tw.utils.isArray(results)) {\n\t\t\t\t\taccumulator = self.makeTiddlerIterator(results);\n\t\t\t\t} else {\n\t\t\t\t\taccumulator = results;\n\t\t\t\t}\n\t\t\t});\n\t\t\tif($tw.utils.isArray(results)) {\n\t\t\t\treturn results;\n\t\t\t} else {\n\t\t\t\tvar resultArray = [];\n\t\t\t\tresults(function(tiddler,title) {\n\t\t\t\t\tresultArray.push(title);\n\t\t\t\t});\n\t\t\t\treturn resultArray;\n\t\t\t}\n\t\t};\n\t\t// Wrap the operator functions in a wrapper function that depends on the prefix\n\t\toperationFunctions.push((function() {\n\t\t\tswitch(operation.prefix || \"\") {\n\t\t\t\tcase \"\": // No prefix means that the operation is unioned into the result\n\t\t\t\t\treturn function(results,source,widget) {\n\t\t\t\t\t\t$tw.utils.pushTop(results,operationSubFunction(source,widget));\n\t\t\t\t\t};\n\t\t\t\tcase \"-\": // The results of this operation are removed from the main result\n\t\t\t\t\treturn function(results,source,widget) {\n\t\t\t\t\t\t$tw.utils.removeArrayEntries(results,operationSubFunction(source,widget));\n\t\t\t\t\t};\n\t\t\t\tcase \"+\": // This operation is applied to the main results so far\n\t\t\t\t\treturn function(results,source,widget) {\n\t\t\t\t\t\t// This replaces all the elements of the array, but keeps the actual array so that references to it are preserved\n\t\t\t\t\t\tsource = self.makeTiddlerIterator(results);\n\t\t\t\t\t\tresults.splice(0,results.length);\n\t\t\t\t\t\t$tw.utils.pushTop(results,operationSubFunction(source,widget));\n\t\t\t\t\t};\n\t\t\t\tcase \"~\": // This operation is unioned into the result only if the main result so far is empty\n\t\t\t\t\treturn function(results,source,widget) {\n\t\t\t\t\t\tif(results.length === 0) {\n\t\t\t\t\t\t\t// Main result so far is empty\n\t\t\t\t\t\t\t$tw.utils.pushTop(results,operationSubFunction(source,widget));\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t}\n\t\t})());\n\t});\n\t// Return a function that applies the operations to a source iterator of tiddler titles\n\treturn $tw.perf.measure(\"filter\",function filterFunction(source,widget) {\n\t\tif(!source) {\n\t\t\tsource = self.each;\n\t\t} else if(typeof source === \"object\") { // Array or hashmap\n\t\t\tsource = self.makeTiddlerIterator(source);\n\t\t}\n\t\tvar results = [];\n\t\t$tw.utils.each(operationFunctions,function(operationFunction) {\n\t\t\toperationFunction(results,source,widget);\n\t\t});\n\t\treturn results;\n\t});\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikimethod"
},
"$:/core/modules/info/platform.js": {
"title": "$:/core/modules/info/platform.js",
"text": "/*\\\ntitle: $:/core/modules/info/platform.js\ntype: application/javascript\nmodule-type: info\n\nInitialise basic platform $:/info/ tiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.getInfoTiddlerFields = function() {\n\tvar mapBoolean = function(value) {return value ? \"yes\" : \"no\";},\n\t\tinfoTiddlerFields = [];\n\t// Basics\n\tinfoTiddlerFields.push({title: \"$:/info/browser\", text: mapBoolean(!!$tw.browser)});\n\tinfoTiddlerFields.push({title: \"$:/info/node\", text: mapBoolean(!!$tw.node)});\n\tif($tw.browser) {\n\t\t// Document location\n\t\tvar setLocationProperty = function(name,value) {\n\t\t\t\tinfoTiddlerFields.push({title: \"$:/info/url/\" + name, text: value});\t\t\t\n\t\t\t},\n\t\t\tlocation = document.location;\n\t\tsetLocationProperty(\"full\", (location.toString()).split(\"#\")[0]);\n\t\tsetLocationProperty(\"host\", location.host);\n\t\tsetLocationProperty(\"hostname\", location.hostname);\n\t\tsetLocationProperty(\"protocol\", location.protocol);\n\t\tsetLocationProperty(\"port\", location.port);\n\t\tsetLocationProperty(\"pathname\", location.pathname);\n\t\tsetLocationProperty(\"search\", location.search);\n\t\tsetLocationProperty(\"origin\", location.origin);\n\t\t// Screen size\n\t\tinfoTiddlerFields.push({title: \"$:/info/browser/screen/width\", text: window.screen.width.toString()});\n\t\tinfoTiddlerFields.push({title: \"$:/info/browser/screen/height\", text: window.screen.height.toString()});\n\t}\n\treturn infoTiddlerFields;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "info"
},
"$:/core/modules/keyboard.js": {
"title": "$:/core/modules/keyboard.js",
"text": "/*\\\ntitle: $:/core/modules/keyboard.js\ntype: application/javascript\nmodule-type: global\n\nKeyboard handling utilities\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar namedKeys = {\n\t\"cancel\": 3,\n\t\"help\": 6,\n\t\"backspace\": 8,\n\t\"tab\": 9,\n\t\"clear\": 12,\n\t\"return\": 13,\n\t\"enter\": 13,\n\t\"pause\": 19,\n\t\"escape\": 27,\n\t\"space\": 32,\n\t\"page_up\": 33,\n\t\"page_down\": 34,\n\t\"end\": 35,\n\t\"home\": 36,\n\t\"left\": 37,\n\t\"up\": 38,\n\t\"right\": 39,\n\t\"down\": 40,\n\t\"printscreen\": 44,\n\t\"insert\": 45,\n\t\"delete\": 46,\n\t\"0\": 48,\n\t\"1\": 49,\n\t\"2\": 50,\n\t\"3\": 51,\n\t\"4\": 52,\n\t\"5\": 53,\n\t\"6\": 54,\n\t\"7\": 55,\n\t\"8\": 56,\n\t\"9\": 57,\n\t\"firefoxsemicolon\": 59,\n\t\"firefoxequals\": 61,\n\t\"a\": 65,\n\t\"b\": 66,\n\t\"c\": 67,\n\t\"d\": 68,\n\t\"e\": 69,\n\t\"f\": 70,\n\t\"g\": 71,\n\t\"h\": 72,\n\t\"i\": 73,\n\t\"j\": 74,\n\t\"k\": 75,\n\t\"l\": 76,\n\t\"m\": 77,\n\t\"n\": 78,\n\t\"o\": 79,\n\t\"p\": 80,\n\t\"q\": 81,\n\t\"r\": 82,\n\t\"s\": 83,\n\t\"t\": 84,\n\t\"u\": 85,\n\t\"v\": 86,\n\t\"w\": 87,\n\t\"x\": 88,\n\t\"y\": 89,\n\t\"z\": 90,\n\t\"numpad0\": 96,\n\t\"numpad1\": 97,\n\t\"numpad2\": 98,\n\t\"numpad3\": 99,\n\t\"numpad4\": 100,\n\t\"numpad5\": 101,\n\t\"numpad6\": 102,\n\t\"numpad7\": 103,\n\t\"numpad8\": 104,\n\t\"numpad9\": 105,\n\t\"multiply\": 106,\n\t\"add\": 107,\n\t\"separator\": 108,\n\t\"subtract\": 109,\n\t\"decimal\": 110,\n\t\"divide\": 111,\n\t\"f1\": 112,\n\t\"f2\": 113,\n\t\"f3\": 114,\n\t\"f4\": 115,\n\t\"f5\": 116,\n\t\"f6\": 117,\n\t\"f7\": 118,\n\t\"f8\": 119,\n\t\"f9\": 120,\n\t\"f10\": 121,\n\t\"f11\": 122,\n\t\"f12\": 123,\n\t\"f13\": 124,\n\t\"f14\": 125,\n\t\"f15\": 126,\n\t\"f16\": 127,\n\t\"f17\": 128,\n\t\"f18\": 129,\n\t\"f19\": 130,\n\t\"f20\": 131,\n\t\"f21\": 132,\n\t\"f22\": 133,\n\t\"f23\": 134,\n\t\"f24\": 135,\n\t\"firefoxminus\": 173,\n\t\"semicolon\": 186,\n\t\"equals\": 187,\n\t\"comma\": 188,\n\t\"dash\": 189,\n\t\"period\": 190,\n\t\"slash\": 191,\n\t\"backquote\": 192,\n\t\"openbracket\": 219,\n\t\"backslash\": 220,\n\t\"closebracket\": 221,\n\t\"quote\": 222\n};\n\nfunction KeyboardManager(options) {\n\tvar self = this;\n\toptions = options || \"\";\n\t// Save the named key hashmap\n\tthis.namedKeys = namedKeys;\n\t// Create a reverse mapping of code to keyname\n\tthis.keyNames = [];\n\t$tw.utils.each(namedKeys,function(keyCode,name) {\n\t\tself.keyNames[keyCode] = name.substr(0,1).toUpperCase() + name.substr(1);\n\t});\n\t// Save the platform-specific name of the \"meta\" key\n\tthis.metaKeyName = $tw.platform.isMac ? \"cmd-\" : \"win-\";\n\tthis.shortcutKeysList = [], // Stores the shortcut-key descriptors\n\tthis.shortcutActionList = [], // Stores the corresponding action strings\n\tthis.shortcutParsedList = []; // Stores the parsed key descriptors\n\tthis.lookupNames = [\"shortcuts\"];\n\tthis.lookupNames.push($tw.platform.isMac ? \"shortcuts-mac\" : \"shortcuts-not-mac\")\n\tthis.lookupNames.push($tw.platform.isWindows ? \"shortcuts-windows\" : \"shortcuts-not-windows\");\n\tthis.lookupNames.push($tw.platform.isLinux ? \"shortcuts-linux\" : \"shortcuts-not-linux\");\n\tthis.updateShortcutLists(this.getShortcutTiddlerList());\n\t$tw.wiki.addEventListener(\"change\",function(changes) {\n\t\tself.handleShortcutChanges(changes);\n\t});\n}\n\n/*\nReturn an array of keycodes for the modifier keys ctrl, shift, alt, meta\n*/\nKeyboardManager.prototype.getModifierKeys = function() {\n\treturn [\n\t\t16, // Shift\n\t\t17, // Ctrl\n\t\t18, // Alt\n\t\t20, // CAPS LOCK\n\t\t91, // Meta (left)\n\t\t93, // Meta (right)\n\t\t224 // Meta (Firefox)\n\t]\n};\n\n/*\nParses a key descriptor into the structure:\n{\n\tkeyCode: numeric keycode\n\tshiftKey: boolean\n\taltKey: boolean\n\tctrlKey: boolean\n\tmetaKey: boolean\n}\nKey descriptors have the following format:\n\tctrl+enter\n\tctrl+shift+alt+A\n*/\nKeyboardManager.prototype.parseKeyDescriptor = function(keyDescriptor) {\n\tvar components = keyDescriptor.split(/\\+|\\-/),\n\t\tinfo = {\n\t\t\tkeyCode: 0,\n\t\t\tshiftKey: false,\n\t\t\taltKey: false,\n\t\t\tctrlKey: false,\n\t\t\tmetaKey: false\n\t\t};\n\tfor(var t=0; t<components.length; t++) {\n\t\tvar s = components[t].toLowerCase(),\n\t\t\tc = s.charCodeAt(0);\n\t\t// Look for modifier keys\n\t\tif(s === \"ctrl\") {\n\t\t\tinfo.ctrlKey = true;\n\t\t} else if(s === \"shift\") {\n\t\t\tinfo.shiftKey = true;\n\t\t} else if(s === \"alt\") {\n\t\t\tinfo.altKey = true;\n\t\t} else if(s === \"meta\" || s === \"cmd\" || s === \"win\") {\n\t\t\tinfo.metaKey = true;\n\t\t}\n\t\t// Replace named keys with their code\n\t\tif(this.namedKeys[s]) {\n\t\t\tinfo.keyCode = this.namedKeys[s];\n\t\t}\n\t}\n\tif(info.keyCode) {\n\t\treturn info;\n\t} else {\n\t\treturn null;\n\t}\n};\n\n/*\nParse a list of key descriptors into an array of keyInfo objects. The key descriptors can be passed as an array of strings or a space separated string\n*/\nKeyboardManager.prototype.parseKeyDescriptors = function(keyDescriptors,options) {\n\tvar self = this;\n\toptions = options || {};\n\toptions.stack = options.stack || [];\n\tvar wiki = options.wiki || $tw.wiki;\n\tif(typeof keyDescriptors === \"string\" && keyDescriptors === \"\") {\n\t\treturn [];\n\t}\n\tif(!$tw.utils.isArray(keyDescriptors)) {\n\t\tkeyDescriptors = keyDescriptors.split(\" \");\n\t}\n\tvar result = [];\n\t$tw.utils.each(keyDescriptors,function(keyDescriptor) {\n\t\t// Look for a named shortcut\n\t\tif(keyDescriptor.substr(0,2) === \"((\" && keyDescriptor.substr(-2,2) === \"))\") {\n\t\t\tif(options.stack.indexOf(keyDescriptor) === -1) {\n\t\t\t\toptions.stack.push(keyDescriptor);\n\t\t\t\tvar name = keyDescriptor.substring(2,keyDescriptor.length - 2),\n\t\t\t\t\tlookupName = function(configName) {\n\t\t\t\t\t\tvar keyDescriptors = wiki.getTiddlerText(\"$:/config/\" + configName + \"/\" + name);\n\t\t\t\t\t\tif(keyDescriptors) {\n\t\t\t\t\t\t\tresult.push.apply(result,self.parseKeyDescriptors(keyDescriptors,options));\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t$tw.utils.each(self.lookupNames,function(platformDescriptor) {\n\t\t\t\t\tlookupName(platformDescriptor);\n\t\t\t\t});\n\t\t\t}\n\t\t} else {\n\t\t\tresult.push(self.parseKeyDescriptor(keyDescriptor));\n\t\t}\n\t});\n\treturn result;\n};\n\nKeyboardManager.prototype.getPrintableShortcuts = function(keyInfoArray) {\n\tvar self = this,\n\t\tresult = [];\n\t$tw.utils.each(keyInfoArray,function(keyInfo) {\n\t\tif(keyInfo) {\n\t\t\tresult.push((keyInfo.ctrlKey ? \"ctrl-\" : \"\") + \n\t\t\t\t (keyInfo.shiftKey ? \"shift-\" : \"\") + \n\t\t\t\t (keyInfo.altKey ? \"alt-\" : \"\") + \n\t\t\t\t (keyInfo.metaKey ? self.metaKeyName : \"\") + \n\t\t\t\t (self.keyNames[keyInfo.keyCode]));\n\t\t}\n\t});\n\treturn result;\n}\n\nKeyboardManager.prototype.checkKeyDescriptor = function(event,keyInfo) {\n\treturn keyInfo &&\n\t\t\tevent.keyCode === keyInfo.keyCode && \n\t\t\tevent.shiftKey === keyInfo.shiftKey && \n\t\t\tevent.altKey === keyInfo.altKey && \n\t\t\tevent.ctrlKey === keyInfo.ctrlKey && \n\t\t\tevent.metaKey === keyInfo.metaKey;\n};\n\nKeyboardManager.prototype.checkKeyDescriptors = function(event,keyInfoArray) {\n\tfor(var t=0; t<keyInfoArray.length; t++) {\n\t\tif(this.checkKeyDescriptor(event,keyInfoArray[t])) {\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n};\n\nKeyboardManager.prototype.getShortcutTiddlerList = function() {\n\treturn $tw.wiki.getTiddlersWithTag(\"$:/tags/KeyboardShortcut\");\n};\n\nKeyboardManager.prototype.updateShortcutLists = function(tiddlerList) {\n\tthis.shortcutTiddlers = tiddlerList;\n\tfor(var i=0; i<tiddlerList.length; i++) {\n\t\tvar title = tiddlerList[i],\n\t\t\ttiddlerFields = $tw.wiki.getTiddler(title).fields;\n\t\tthis.shortcutKeysList[i] = tiddlerFields.key !== undefined ? tiddlerFields.key : undefined;\n\t\tthis.shortcutActionList[i] = tiddlerFields.text;\n\t\tthis.shortcutParsedList[i] = this.shortcutKeysList[i] !== undefined ? this.parseKeyDescriptors(this.shortcutKeysList[i]) : undefined;\n\t}\n};\n\nKeyboardManager.prototype.handleKeydownEvent = function(event) {\n\tvar key, action;\n\tfor(var i=0; i<this.shortcutTiddlers.length; i++) {\n\t\tif(this.shortcutParsedList[i] !== undefined && this.checkKeyDescriptors(event,this.shortcutParsedList[i])) {\n\t\t\tkey = this.shortcutParsedList[i];\n\t\t\taction = this.shortcutActionList[i];\n\t\t}\n\t}\n\tif(key !== undefined) {\n\t\tevent.preventDefault();\n\t\tevent.stopPropagation();\n\t\t$tw.rootWidget.invokeActionString(action,$tw.rootWidget);\n\t\treturn true;\n\t}\n\treturn false;\n};\n\nKeyboardManager.prototype.detectNewShortcuts = function(changedTiddlers) {\n\tvar shortcutConfigTiddlers = [],\n\t\thandled = false;\n\t$tw.utils.each(this.lookupNames,function(platformDescriptor) {\n\t\tvar descriptorString = \"$:/config/\" + platformDescriptor + \"/\";\n\t\tObject.keys(changedTiddlers).forEach(function(configTiddler) {\n\t\t\tvar configString = configTiddler.substr(0, configTiddler.lastIndexOf(\"/\") + 1);\n\t\t\tif(configString === descriptorString) {\n\t\t\t\tshortcutConfigTiddlers.push(configTiddler);\n\t\t\t\thandled = true;\n\t\t\t}\n\t\t});\n\t});\n\tif(handled) {\n\t\treturn $tw.utils.hopArray(changedTiddlers,shortcutConfigTiddlers);\n\t} else {\n\t\treturn false;\n\t}\n};\n\nKeyboardManager.prototype.handleShortcutChanges = function(changedTiddlers) {\n\tvar newList = this.getShortcutTiddlerList();\n\tvar hasChanged = $tw.utils.hopArray(changedTiddlers,this.shortcutTiddlers) ? true :\n\t\t($tw.utils.hopArray(changedTiddlers,newList) ? true :\n\t\t(this.detectNewShortcuts(changedTiddlers))\n\t);\n\t// Re-cache shortcuts if something changed\n\tif(hasChanged) {\n\t\tthis.updateShortcutLists(newList);\n\t}\n};\n\nexports.KeyboardManager = KeyboardManager;\n\n})();\n",
"type": "application/javascript",
"module-type": "global"
},
"$:/core/modules/language.js": {
"title": "$:/core/modules/language.js",
"text": "/*\\\ntitle: $:/core/modules/language.js\ntype: application/javascript\nmodule-type: global\n\nThe $tw.Language() manages translateable strings\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nCreate an instance of the language manager. Options include:\nwiki: wiki from which to retrieve translation tiddlers\n*/\nfunction Language(options) {\n\toptions = options || \"\";\n\tthis.wiki = options.wiki || $tw.wiki;\n}\n\n/*\nReturn a wikified translateable string. The title is automatically prefixed with \"$:/language/\"\nOptions include:\nvariables: optional hashmap of variables to supply to the language wikification\n*/\nLanguage.prototype.getString = function(title,options) {\n\toptions = options || {};\n\ttitle = \"$:/language/\" + title;\n\treturn this.wiki.renderTiddler(\"text/plain\",title,{variables: options.variables});\n};\n\n/*\nReturn a raw, unwikified translateable string. The title is automatically prefixed with \"$:/language/\"\n*/\nLanguage.prototype.getRawString = function(title) {\n\ttitle = \"$:/language/\" + title;\n\treturn this.wiki.getTiddlerText(title);\n};\n\nexports.Language = Language;\n\n})();\n",
"type": "application/javascript",
"module-type": "global"
},
"$:/core/modules/macros/changecount.js": {
"title": "$:/core/modules/macros/changecount.js",
"text": "/*\\\ntitle: $:/core/modules/macros/changecount.js\ntype: application/javascript\nmodule-type: macro\n\nMacro to return the changecount for the current tiddler\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nInformation about this macro\n*/\n\nexports.name = \"changecount\";\n\nexports.params = [];\n\n/*\nRun the macro\n*/\nexports.run = function() {\n\treturn this.wiki.getChangeCount(this.getVariable(\"currentTiddler\")) + \"\";\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "macro"
},
"$:/core/modules/macros/contrastcolour.js": {
"title": "$:/core/modules/macros/contrastcolour.js",
"text": "/*\\\ntitle: $:/core/modules/macros/contrastcolour.js\ntype: application/javascript\nmodule-type: macro\n\nMacro to choose which of two colours has the highest contrast with a base colour\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nInformation about this macro\n*/\n\nexports.name = \"contrastcolour\";\n\nexports.params = [\n\t{name: \"target\"},\n\t{name: \"fallbackTarget\"},\n\t{name: \"colourA\"},\n\t{name: \"colourB\"}\n];\n\n/*\nRun the macro\n*/\nexports.run = function(target,fallbackTarget,colourA,colourB) {\n\tvar rgbTarget = $tw.utils.parseCSSColor(target) || $tw.utils.parseCSSColor(fallbackTarget);\n\tif(!rgbTarget) {\n\t\treturn colourA;\n\t}\n\tvar rgbColourA = $tw.utils.parseCSSColor(colourA),\n\t\trgbColourB = $tw.utils.parseCSSColor(colourB);\n\tif(rgbColourA && !rgbColourB) {\n\t\treturn rgbColourA;\n\t}\n\tif(rgbColourB && !rgbColourA) {\n\t\treturn rgbColourB;\n\t}\n\tif(!rgbColourA && !rgbColourB) {\n\t\t// If neither colour is readable, return a crude inverse of the target\n\t\treturn [255 - rgbTarget[0],255 - rgbTarget[1],255 - rgbTarget[2],rgbTarget[3]];\n\t}\n\t// Colour brightness formula derived from http://www.w3.org/WAI/ER/WD-AERT/#color-contrast\n\tvar brightnessTarget = rgbTarget[0] * 0.299 + rgbTarget[1] * 0.587 + rgbTarget[2] * 0.114,\n\t\tbrightnessA = rgbColourA[0] * 0.299 + rgbColourA[1] * 0.587 + rgbColourA[2] * 0.114,\n\t\tbrightnessB = rgbColourB[0] * 0.299 + rgbColourB[1] * 0.587 + rgbColourB[2] * 0.114;\n\treturn Math.abs(brightnessTarget - brightnessA) > Math.abs(brightnessTarget - brightnessB) ? colourA : colourB;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "macro"
},
"$:/core/modules/macros/csvtiddlers.js": {
"title": "$:/core/modules/macros/csvtiddlers.js",
"text": "/*\\\ntitle: $:/core/modules/macros/csvtiddlers.js\ntype: application/javascript\nmodule-type: macro\n\nMacro to output tiddlers matching a filter to CSV\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nInformation about this macro\n*/\n\nexports.name = \"csvtiddlers\";\n\nexports.params = [\n\t{name: \"filter\"},\n\t{name: \"format\"},\n];\n\n/*\nRun the macro\n*/\nexports.run = function(filter,format) {\n\tvar self = this,\n\t\ttiddlers = this.wiki.filterTiddlers(filter),\n\t\ttiddler,\n\t\tfields = [],\n\t\tt,f;\n\t// Collect all the fields\n\tfor(t=0;t<tiddlers.length; t++) {\n\t\ttiddler = this.wiki.getTiddler(tiddlers[t]);\n\t\tfor(f in tiddler.fields) {\n\t\t\tif(fields.indexOf(f) === -1) {\n\t\t\t\tfields.push(f);\n\t\t\t}\n\t\t}\n\t}\n\t// Sort the fields and bring the standard ones to the front\n\tfields.sort();\n\t\"title text modified modifier created creator\".split(\" \").reverse().forEach(function(value,index) {\n\t\tvar p = fields.indexOf(value);\n\t\tif(p !== -1) {\n\t\t\tfields.splice(p,1);\n\t\t\tfields.unshift(value)\n\t\t}\n\t});\n\t// Output the column headings\n\tvar output = [], row = [];\n\tfields.forEach(function(value) {\n\t\trow.push(quoteAndEscape(value))\n\t});\n\toutput.push(row.join(\",\"));\n\t// Output each tiddler\n\tfor(var t=0;t<tiddlers.length; t++) {\n\t\trow = [];\n\t\ttiddler = this.wiki.getTiddler(tiddlers[t]);\n\t\t\tfor(f=0; f<fields.length; f++) {\n\t\t\t\trow.push(quoteAndEscape(tiddler ? tiddler.getFieldString(fields[f]) || \"\" : \"\"));\n\t\t\t}\n\t\toutput.push(row.join(\",\"));\n\t}\n\treturn output.join(\"\\n\");\n};\n\nfunction quoteAndEscape(value) {\n\treturn \"\\\"\" + value.replace(/\"/mg,\"\\\"\\\"\") + \"\\\"\";\n}\n\n})();\n",
"type": "application/javascript",
"module-type": "macro"
},
"$:/core/modules/macros/displayshortcuts.js": {
"title": "$:/core/modules/macros/displayshortcuts.js",
"text": "/*\\\ntitle: $:/core/modules/macros/displayshortcuts.js\ntype: application/javascript\nmodule-type: macro\n\nMacro to display a list of keyboard shortcuts in human readable form. Notably, it resolves named shortcuts like `((bold))` to the underlying keystrokes.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nInformation about this macro\n*/\n\nexports.name = \"displayshortcuts\";\n\nexports.params = [\n\t{name: \"shortcuts\"},\n\t{name: \"prefix\"},\n\t{name: \"separator\"},\n\t{name: \"suffix\"}\n];\n\n/*\nRun the macro\n*/\nexports.run = function(shortcuts,prefix,separator,suffix) {\n\tvar shortcutArray = $tw.keyboardManager.getPrintableShortcuts($tw.keyboardManager.parseKeyDescriptors(shortcuts,{\n\t\twiki: this.wiki\n\t}));\n\tif(shortcutArray.length > 0) {\n\t\tshortcutArray.sort(function(a,b) {\n\t\t return a.toLowerCase().localeCompare(b.toLowerCase());\n\t\t})\n\t\treturn prefix + shortcutArray.join(separator) + suffix;\n\t} else {\n\t\treturn \"\";\n\t}\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "macro"
},
"$:/core/modules/macros/dumpvariables.js": {
"title": "$:/core/modules/macros/dumpvariables.js",
"text": "/*\\\ntitle: $:/core/modules/macros/dumpvariables.js\ntype: application/javascript\nmodule-type: macro\n\nMacro to dump all active variable values\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nInformation about this macro\n*/\n\nexports.name = \"dumpvariables\";\n\nexports.params = [\n];\n\n/*\nRun the macro\n*/\nexports.run = function() {\n\tvar output = [\"|!Variable |!Value |\"],\n\t\tvariables = [], variable;\n\tfor(variable in this.variables) {\n\t\tvariables.push(variable);\n\t}\n\tvariables.sort();\n\tfor(var index=0; index<variables.length; index++) {\n\t\tvar variable = variables[index];\n\t\toutput.push(\"|\" + variable + \" |<input size=50 value=<<\" + variable + \">>/> |\")\n\t}\n\treturn output.join(\"\\n\");\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "macro"
},
"$:/core/modules/macros/jsontiddler.js": {
"title": "$:/core/modules/macros/jsontiddler.js",
"text": "/*\\\ntitle: $:/core/modules/macros/jsontiddler.js\ntype: application/javascript\nmodule-type: macro\n\nMacro to output a single tiddler to JSON\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nInformation about this macro\n*/\n\nexports.name = \"jsontiddler\";\n\nexports.params = [\n\t{name: \"title\"}\n];\n\n/*\nRun the macro\n*/\nexports.run = function(title) {\n\ttitle = title || this.getVariable(\"currentTiddler\");\n\tvar tiddler = !!title && this.wiki.getTiddler(title),\n\t\tfields = new Object();\n\tif(tiddler) {\n\t\tfor(var field in tiddler.fields) {\n\t\t\tfields[field] = tiddler.getFieldString(field);\n\t\t}\n\t}\n\treturn JSON.stringify(fields,null,$tw.config.preferences.jsonSpaces);\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "macro"
},
"$:/core/modules/macros/jsontiddlers.js": {
"title": "$:/core/modules/macros/jsontiddlers.js",
"text": "/*\\\ntitle: $:/core/modules/macros/jsontiddlers.js\ntype: application/javascript\nmodule-type: macro\n\nMacro to output tiddlers matching a filter to JSON\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nInformation about this macro\n*/\n\nexports.name = \"jsontiddlers\";\n\nexports.params = [\n\t{name: \"filter\"}\n];\n\n/*\nRun the macro\n*/\nexports.run = function(filter) {\n\treturn this.wiki.getTiddlersAsJson(filter);\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "macro"
},
"$:/core/modules/macros/makedatauri.js": {
"title": "$:/core/modules/macros/makedatauri.js",
"text": "/*\\\ntitle: $:/core/modules/macros/makedatauri.js\ntype: application/javascript\nmodule-type: macro\n\nMacro to convert a string of text to a data URI\n\n<<makedatauri text:\"Text to be converted\" type:\"text/vnd.tiddlywiki\">>\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nInformation about this macro\n*/\n\nexports.name = \"makedatauri\";\n\nexports.params = [\n\t{name: \"text\"},\n\t{name: \"type\"}\n];\n\n/*\nRun the macro\n*/\nexports.run = function(text,type) {\n\treturn $tw.utils.makeDataUri(text,type);\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "macro"
},
"$:/core/modules/macros/now.js": {
"title": "$:/core/modules/macros/now.js",
"text": "/*\\\ntitle: $:/core/modules/macros/now.js\ntype: application/javascript\nmodule-type: macro\n\nMacro to return a formatted version of the current time\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nInformation about this macro\n*/\n\nexports.name = \"now\";\n\nexports.params = [\n\t{name: \"format\"}\n];\n\n/*\nRun the macro\n*/\nexports.run = function(format) {\n\treturn $tw.utils.formatDateString(new Date(),format || \"0hh:0mm, DDth MMM YYYY\");\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "macro"
},
"$:/core/modules/macros/qualify.js": {
"title": "$:/core/modules/macros/qualify.js",
"text": "/*\\\ntitle: $:/core/modules/macros/qualify.js\ntype: application/javascript\nmodule-type: macro\n\nMacro to qualify a state tiddler title according\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nInformation about this macro\n*/\n\nexports.name = \"qualify\";\n\nexports.params = [\n\t{name: \"title\"}\n];\n\n/*\nRun the macro\n*/\nexports.run = function(title) {\n\treturn title + \"-\" + this.getStateQualifier();\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "macro"
},
"$:/core/modules/macros/resolvepath.js": {
"title": "$:/core/modules/macros/resolvepath.js",
"text": "/*\\\ntitle: $:/core/modules/macros/resolvepath.js\ntype: application/javascript\nmodule-type: macro\n\nResolves a relative path for an absolute rootpath.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"resolvepath\";\n\nexports.params = [\n\t{name: \"source\"},\n\t{name: \"root\"}\n];\n\n/*\nRun the macro\n*/\nexports.run = function(source, root) {\n\treturn $tw.utils.resolvePath(source, root);\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "macro"
},
"$:/core/modules/macros/version.js": {
"title": "$:/core/modules/macros/version.js",
"text": "/*\\\ntitle: $:/core/modules/macros/version.js\ntype: application/javascript\nmodule-type: macro\n\nMacro to return the TiddlyWiki core version number\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nInformation about this macro\n*/\n\nexports.name = \"version\";\n\nexports.params = [];\n\n/*\nRun the macro\n*/\nexports.run = function() {\n\treturn $tw.version;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "macro"
},
"$:/core/modules/parsers/audioparser.js": {
"title": "$:/core/modules/parsers/audioparser.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/audioparser.js\ntype: application/javascript\nmodule-type: parser\n\nThe audio parser parses an audio tiddler into an embeddable HTML element\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar AudioParser = function(type,text,options) {\n\tvar element = {\n\t\t\ttype: \"element\",\n\t\t\ttag: \"audio\",\n\t\t\tattributes: {\n\t\t\t\tcontrols: {type: \"string\", value: \"controls\"}\n\t\t\t}\n\t\t},\n\t\tsrc;\n\tif(options._canonical_uri) {\n\t\telement.attributes.src = {type: \"string\", value: options._canonical_uri};\n\t} else if(text) {\n\t\telement.attributes.src = {type: \"string\", value: \"data:\" + type + \";base64,\" + text};\n\t}\n\tthis.tree = [element];\n};\n\nexports[\"audio/ogg\"] = AudioParser;\nexports[\"audio/mpeg\"] = AudioParser;\nexports[\"audio/mp3\"] = AudioParser;\nexports[\"audio/mp4\"] = AudioParser;\n\n})();\n\n",
"type": "application/javascript",
"module-type": "parser"
},
"$:/core/modules/parsers/binaryparser.js": {
"title": "$:/core/modules/parsers/binaryparser.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/binaryparser.js\ntype: application/javascript\nmodule-type: parser\n\nThe video parser parses a video tiddler into an embeddable HTML element\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar BINARY_WARNING_MESSAGE = \"$:/core/ui/BinaryWarning\";\n\nvar BinaryParser = function(type,text,options) {\n\tthis.tree = [{\n\t\ttype: \"transclude\",\n\t\tattributes: {\n\t\t\ttiddler: {type: \"string\", value: BINARY_WARNING_MESSAGE}\n\t\t}\n\t}];\n};\n\nexports[\"application/octet-stream\"] = BinaryParser;\n\n})();\n\n",
"type": "application/javascript",
"module-type": "parser"
},
"$:/core/modules/parsers/csvparser.js": {
"title": "$:/core/modules/parsers/csvparser.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/csvparser.js\ntype: application/javascript\nmodule-type: parser\n\nThe CSV text parser processes CSV files into a table wrapped in a scrollable widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar CsvParser = function(type,text,options) {\n\t// Table framework\n\tthis.tree = [{\n\t\t\"type\": \"scrollable\", \"children\": [{\n\t\t\t\"type\": \"element\", \"tag\": \"table\", \"children\": [{\n\t\t\t\t\"type\": \"element\", \"tag\": \"tbody\", \"children\": []\n\t\t\t}], \"attributes\": {\n\t\t\t\t\"class\": {\"type\": \"string\", \"value\": \"tc-csv-table\"}\n\t\t\t}\n\t\t}]\n\t}];\n\t// Split the text into lines\n\tvar lines = text.split(/\\r?\\n/mg),\n\t\ttag = \"th\";\n\tfor(var line=0; line<lines.length; line++) {\n\t\tvar lineText = lines[line];\n\t\tif(lineText) {\n\t\t\tvar row = {\n\t\t\t\t\t\"type\": \"element\", \"tag\": \"tr\", \"children\": []\n\t\t\t\t};\n\t\t\tvar columns = lineText.split(\",\");\n\t\t\tfor(var column=0; column<columns.length; column++) {\n\t\t\t\trow.children.push({\n\t\t\t\t\t\t\"type\": \"element\", \"tag\": tag, \"children\": [{\n\t\t\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\t\t\"text\": columns[column]\n\t\t\t\t\t\t}]\n\t\t\t\t\t});\n\t\t\t}\n\t\t\ttag = \"td\";\n\t\t\tthis.tree[0].children[0].children[0].children.push(row);\n\t\t}\n\t}\n};\n\nexports[\"text/csv\"] = CsvParser;\n\n})();\n\n",
"type": "application/javascript",
"module-type": "parser"
},
"$:/core/modules/parsers/htmlparser.js": {
"title": "$:/core/modules/parsers/htmlparser.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/htmlparser.js\ntype: application/javascript\nmodule-type: parser\n\nThe HTML parser displays text as raw HTML\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar HtmlParser = function(type,text,options) {\n\tvar src;\n\tif(options._canonical_uri) {\n\t\tsrc = options._canonical_uri;\n\t} else if(text) {\n\t\tsrc = \"data:text/html;charset=utf-8,\" + encodeURIComponent(text);\n\t}\n\tthis.tree = [{\n\t\ttype: \"element\",\n\t\ttag: \"iframe\",\n\t\tattributes: {\n\t\t\tsrc: {type: \"string\", value: src},\n\t\t\tsandbox: {type: \"string\", value: \"\"}\n\t\t}\n\t}];\n};\n\nexports[\"text/html\"] = HtmlParser;\n\n})();\n\n",
"type": "application/javascript",
"module-type": "parser"
},
"$:/core/modules/parsers/imageparser.js": {
"title": "$:/core/modules/parsers/imageparser.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/imageparser.js\ntype: application/javascript\nmodule-type: parser\n\nThe image parser parses an image into an embeddable HTML element\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar ImageParser = function(type,text,options) {\n\tvar element = {\n\t\t\ttype: \"element\",\n\t\t\ttag: \"img\",\n\t\t\tattributes: {}\n\t\t};\n\tif(options._canonical_uri) {\n\t\telement.attributes.src = {type: \"string\", value: options._canonical_uri};\n\t} else if(text) {\n\t\tif(type === \"image/svg+xml\" || type === \".svg\") {\n\t\t\telement.attributes.src = {type: \"string\", value: \"data:image/svg+xml,\" + encodeURIComponent(text)};\n\t\t} else {\n\t\t\telement.attributes.src = {type: \"string\", value: \"data:\" + type + \";base64,\" + text};\n\t\t}\n\t}\n\tthis.tree = [element];\n};\n\nexports[\"image/svg+xml\"] = ImageParser;\nexports[\"image/jpg\"] = ImageParser;\nexports[\"image/jpeg\"] = ImageParser;\nexports[\"image/png\"] = ImageParser;\nexports[\"image/gif\"] = ImageParser;\nexports[\"image/webp\"] = ImageParser;\nexports[\"image/heic\"] = ImageParser;\nexports[\"image/heif\"] = ImageParser;\nexports[\"image/x-icon\"] = ImageParser;\n\n})();\n\n",
"type": "application/javascript",
"module-type": "parser"
},
"$:/core/modules/utils/parseutils.js": {
"title": "$:/core/modules/utils/parseutils.js",
"text": "/*\\\ntitle: $:/core/modules/utils/parseutils.js\ntype: application/javascript\nmodule-type: utils\n\nUtility functions concerned with parsing text into tokens.\n\nMost functions have the following pattern:\n\n* The parameters are:\n** `source`: the source string being parsed\n** `pos`: the current parse position within the string\n** Any further parameters are used to identify the token that is being parsed\n* The return value is:\n** null if the token was not found at the specified position\n** an object representing the token with the following standard fields:\n*** `type`: string indicating the type of the token\n*** `start`: start position of the token in the source string\n*** `end`: end position of the token in the source string\n*** Any further fields required to describe the token\n\nThe exception is `skipWhiteSpace`, which just returns the position after the whitespace.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nLook for a whitespace token. Returns null if not found, otherwise returns {type: \"whitespace\", start:, end:,}\n*/\nexports.parseWhiteSpace = function(source,pos) {\n\tvar p = pos,c;\n\twhile(true) {\n\t\tc = source.charAt(p);\n\t\tif((c === \" \") || (c === \"\\f\") || (c === \"\\n\") || (c === \"\\r\") || (c === \"\\t\") || (c === \"\\v\") || (c === \"\\u00a0\")) { // Ignores some obscure unicode spaces\n\t\t\tp++;\n\t\t} else {\n\t\t\tbreak;\n\t\t}\n\t}\n\tif(p === pos) {\n\t\treturn null;\n\t} else {\n\t\treturn {\n\t\t\ttype: \"whitespace\",\n\t\t\tstart: pos,\n\t\t\tend: p\n\t\t}\n\t}\n};\n\n/*\nConvenience wrapper for parseWhiteSpace. Returns the position after the whitespace\n*/\nexports.skipWhiteSpace = function(source,pos) {\n\tvar c;\n\twhile(true) {\n\t\tc = source.charAt(pos);\n\t\tif((c === \" \") || (c === \"\\f\") || (c === \"\\n\") || (c === \"\\r\") || (c === \"\\t\") || (c === \"\\v\") || (c === \"\\u00a0\")) { // Ignores some obscure unicode spaces\n\t\t\tpos++;\n\t\t} else {\n\t\t\treturn pos;\n\t\t}\n\t}\n};\n\n/*\nLook for a given string token. Returns null if not found, otherwise returns {type: \"token\", value:, start:, end:,}\n*/\nexports.parseTokenString = function(source,pos,token) {\n\tvar match = source.indexOf(token,pos) === pos;\n\tif(match) {\n\t\treturn {\n\t\t\ttype: \"token\",\n\t\t\tvalue: token,\n\t\t\tstart: pos,\n\t\t\tend: pos + token.length\n\t\t};\n\t}\n\treturn null;\n};\n\n/*\nLook for a token matching a regex. Returns null if not found, otherwise returns {type: \"regexp\", match:, start:, end:,}\n*/\nexports.parseTokenRegExp = function(source,pos,reToken) {\n\tvar node = {\n\t\ttype: \"regexp\",\n\t\tstart: pos\n\t};\n\treToken.lastIndex = pos;\n\tnode.match = reToken.exec(source);\n\tif(node.match && node.match.index === pos) {\n\t\tnode.end = pos + node.match[0].length;\n\t\treturn node;\n\t} else {\n\t\treturn null;\n\t}\n};\n\n/*\nLook for a string literal. Returns null if not found, otherwise returns {type: \"string\", value:, start:, end:,}\n*/\nexports.parseStringLiteral = function(source,pos) {\n\tvar node = {\n\t\ttype: \"string\",\n\t\tstart: pos\n\t};\n\tvar reString = /(?:\"\"\"([\\s\\S]*?)\"\"\"|\"([^\"]*)\")|(?:'([^']*)')/g;\n\treString.lastIndex = pos;\n\tvar match = reString.exec(source);\n\tif(match && match.index === pos) {\n\t\tnode.value = match[1] !== undefined ? match[1] :(\n\t\t\tmatch[2] !== undefined ? match[2] : match[3] \n\t\t\t\t\t);\n\t\tnode.end = pos + match[0].length;\n\t\treturn node;\n\t} else {\n\t\treturn null;\n\t}\n};\n\n/*\nLook for a macro invocation parameter. Returns null if not found, or {type: \"macro-parameter\", name:, value:, start:, end:}\n*/\nexports.parseMacroParameter = function(source,pos) {\n\tvar node = {\n\t\ttype: \"macro-parameter\",\n\t\tstart: pos\n\t};\n\t// Define our regexp\n\tvar reMacroParameter = /(?:([A-Za-z0-9\\-_]+)\\s*:)?(?:\\s*(?:\"\"\"([\\s\\S]*?)\"\"\"|\"([^\"]*)\"|'([^']*)'|\\[\\[([^\\]]*)\\]\\]|([^\\s>\"'=]+)))/g;\n\t// Skip whitespace\n\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t// Look for the parameter\n\tvar token = $tw.utils.parseTokenRegExp(source,pos,reMacroParameter);\n\tif(!token) {\n\t\treturn null;\n\t}\n\tpos = token.end;\n\t// Get the parameter details\n\tnode.value = token.match[2] !== undefined ? token.match[2] : (\n\t\t\t\t\ttoken.match[3] !== undefined ? token.match[3] : (\n\t\t\t\t\t\ttoken.match[4] !== undefined ? token.match[4] : (\n\t\t\t\t\t\t\ttoken.match[5] !== undefined ? token.match[5] : (\n\t\t\t\t\t\t\t\ttoken.match[6] !== undefined ? token.match[6] : (\n\t\t\t\t\t\t\t\t\t\"\"\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t)\n\t\t\t\t\t)\n\t\t\t\t);\n\tif(token.match[1]) {\n\t\tnode.name = token.match[1];\n\t}\n\t// Update the end position\n\tnode.end = pos;\n\treturn node;\n};\n\n/*\nLook for a macro invocation. Returns null if not found, or {type: \"macrocall\", name:, parameters:, start:, end:}\n*/\nexports.parseMacroInvocation = function(source,pos) {\n\tvar node = {\n\t\ttype: \"macrocall\",\n\t\tstart: pos,\n\t\tparams: []\n\t};\n\t// Define our regexps\n\tvar reMacroName = /([^\\s>\"'=]+)/g;\n\t// Skip whitespace\n\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t// Look for a double less than sign\n\tvar token = $tw.utils.parseTokenString(source,pos,\"<<\");\n\tif(!token) {\n\t\treturn null;\n\t}\n\tpos = token.end;\n\t// Get the macro name\n\tvar name = $tw.utils.parseTokenRegExp(source,pos,reMacroName);\n\tif(!name) {\n\t\treturn null;\n\t}\n\tnode.name = name.match[1];\n\tpos = name.end;\n\t// Process parameters\n\tvar parameter = $tw.utils.parseMacroParameter(source,pos);\n\twhile(parameter) {\n\t\tnode.params.push(parameter);\n\t\tpos = parameter.end;\n\t\t// Get the next parameter\n\t\tparameter = $tw.utils.parseMacroParameter(source,pos);\n\t}\n\t// Skip whitespace\n\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t// Look for a double greater than sign\n\ttoken = $tw.utils.parseTokenString(source,pos,\">>\");\n\tif(!token) {\n\t\treturn null;\n\t}\n\tpos = token.end;\n\t// Update the end position\n\tnode.end = pos;\n\treturn node;\n};\n\n/*\nLook for an HTML attribute definition. Returns null if not found, otherwise returns {type: \"attribute\", name:, valueType: \"string|indirect|macro\", value:, start:, end:,}\n*/\nexports.parseAttribute = function(source,pos) {\n\tvar node = {\n\t\tstart: pos\n\t};\n\t// Define our regexps\n\tvar reAttributeName = /([^\\/\\s>\"'=]+)/g,\n\t\treUnquotedAttribute = /([^\\/\\s<>\"'=]+)/g,\n\t\treFilteredValue = /\\{\\{\\{(.+?)\\}\\}\\}/g,\n\t\treIndirectValue = /\\{\\{([^\\}]+)\\}\\}/g;\n\t// Skip whitespace\n\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t// Get the attribute name\n\tvar name = $tw.utils.parseTokenRegExp(source,pos,reAttributeName);\n\tif(!name) {\n\t\treturn null;\n\t}\n\tnode.name = name.match[1];\n\tpos = name.end;\n\t// Skip whitespace\n\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t// Look for an equals sign\n\tvar token = $tw.utils.parseTokenString(source,pos,\"=\");\n\tif(token) {\n\t\tpos = token.end;\n\t\t// Skip whitespace\n\t\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t\t// Look for a string literal\n\t\tvar stringLiteral = $tw.utils.parseStringLiteral(source,pos);\n\t\tif(stringLiteral) {\n\t\t\tpos = stringLiteral.end;\n\t\t\tnode.type = \"string\";\n\t\t\tnode.value = stringLiteral.value;\n\t\t} else {\n\t\t\t// Look for a filtered value\n\t\t\tvar filteredValue = $tw.utils.parseTokenRegExp(source,pos,reFilteredValue);\n\t\t\tif(filteredValue) {\n\t\t\t\tpos = filteredValue.end;\n\t\t\t\tnode.type = \"filtered\";\n\t\t\t\tnode.filter = filteredValue.match[1];\n\t\t\t} else {\n\t\t\t\t// Look for an indirect value\n\t\t\t\tvar indirectValue = $tw.utils.parseTokenRegExp(source,pos,reIndirectValue);\n\t\t\t\tif(indirectValue) {\n\t\t\t\t\tpos = indirectValue.end;\n\t\t\t\t\tnode.type = \"indirect\";\n\t\t\t\t\tnode.textReference = indirectValue.match[1];\n\t\t\t\t} else {\n\t\t\t\t\t// Look for a unquoted value\n\t\t\t\t\tvar unquotedValue = $tw.utils.parseTokenRegExp(source,pos,reUnquotedAttribute);\n\t\t\t\t\tif(unquotedValue) {\n\t\t\t\t\t\tpos = unquotedValue.end;\n\t\t\t\t\t\tnode.type = \"string\";\n\t\t\t\t\t\tnode.value = unquotedValue.match[1];\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Look for a macro invocation value\n\t\t\t\t\t\tvar macroInvocation = $tw.utils.parseMacroInvocation(source,pos);\n\t\t\t\t\t\tif(macroInvocation) {\n\t\t\t\t\t\t\tpos = macroInvocation.end;\n\t\t\t\t\t\t\tnode.type = \"macro\";\n\t\t\t\t\t\t\tnode.value = macroInvocation;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tnode.type = \"string\";\n\t\t\t\t\t\t\tnode.value = \"true\";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else {\n\t\tnode.type = \"string\";\n\t\tnode.value = \"true\";\n\t}\n\t// Update the end position\n\tnode.end = pos;\n\treturn node;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "utils"
},
"$:/core/modules/parsers/pdfparser.js": {
"title": "$:/core/modules/parsers/pdfparser.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/pdfparser.js\ntype: application/javascript\nmodule-type: parser\n\nThe PDF parser embeds a PDF viewer\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar ImageParser = function(type,text,options) {\n\tvar element = {\n\t\t\ttype: \"element\",\n\t\t\ttag: \"embed\",\n\t\t\tattributes: {}\n\t\t},\n\t\tsrc;\n\tif(options._canonical_uri) {\n\t\telement.attributes.src = {type: \"string\", value: options._canonical_uri};\n\t} else if(text) {\n\t\telement.attributes.src = {type: \"string\", value: \"data:application/pdf;base64,\" + text};\n\t}\n\tthis.tree = [element];\n};\n\nexports[\"application/pdf\"] = ImageParser;\n\n})();\n\n",
"type": "application/javascript",
"module-type": "parser"
},
"$:/core/modules/parsers/textparser.js": {
"title": "$:/core/modules/parsers/textparser.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/textparser.js\ntype: application/javascript\nmodule-type: parser\n\nThe plain text parser processes blocks of source text into a degenerate parse tree consisting of a single text node\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar TextParser = function(type,text,options) {\n\tthis.tree = [{\n\t\ttype: \"codeblock\",\n\t\tattributes: {\n\t\t\tcode: {type: \"string\", value: text},\n\t\t\tlanguage: {type: \"string\", value: type}\n\t\t}\n\t}];\n};\n\nexports[\"text/plain\"] = TextParser;\nexports[\"text/x-tiddlywiki\"] = TextParser;\nexports[\"application/javascript\"] = TextParser;\nexports[\"application/json\"] = TextParser;\nexports[\"text/css\"] = TextParser;\nexports[\"application/x-tiddler-dictionary\"] = TextParser;\n\n})();\n\n",
"type": "application/javascript",
"module-type": "parser"
},
"$:/core/modules/parsers/videoparser.js": {
"title": "$:/core/modules/parsers/videoparser.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/videoparser.js\ntype: application/javascript\nmodule-type: parser\n\nThe video parser parses a video tiddler into an embeddable HTML element\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar VideoParser = function(type,text,options) {\n\tvar element = {\n\t\t\ttype: \"element\",\n\t\t\ttag: \"video\",\n\t\t\tattributes: {\n\t\t\t\tcontrols: {type: \"string\", value: \"controls\"}\n\t\t\t}\n\t\t},\n\t\tsrc;\n\tif(options._canonical_uri) {\n\t\telement.attributes.src = {type: \"string\", value: options._canonical_uri};\n\t} else if(text) {\n\t\telement.attributes.src = {type: \"string\", value: \"data:\" + type + \";base64,\" + text};\n\t}\n\tthis.tree = [element];\n};\n\nexports[\"video/mp4\"] = VideoParser;\nexports[\"video/quicktime\"] = VideoParser;\n\n})();\n\n",
"type": "application/javascript",
"module-type": "parser"
},
"$:/core/modules/parsers/wikiparser/rules/codeblock.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/codeblock.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/codeblock.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text rule for code blocks. For example:\n\n```\n\t```\n\tThis text will not be //wikified//\n\t```\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"codeblock\";\nexports.types = {block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match and get language if defined\n\tthis.matchRegExp = /```([\\w-]*)\\r?\\n/mg;\n};\n\nexports.parse = function() {\n\tvar reEnd = /(\\r?\\n```$)/mg;\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\n\t// Look for the end of the block\n\treEnd.lastIndex = this.parser.pos;\n\tvar match = reEnd.exec(this.parser.source),\n\t\ttext;\n\t// Process the block\n\tif(match) {\n\t\ttext = this.parser.source.substring(this.parser.pos,match.index);\n\t\tthis.parser.pos = match.index + match[0].length;\n\t} else {\n\t\ttext = this.parser.source.substr(this.parser.pos);\n\t\tthis.parser.pos = this.parser.sourceLength;\n\t}\n\t// Return the $codeblock widget\n\treturn [{\n\t\t\ttype: \"codeblock\",\n\t\t\tattributes: {\n\t\t\t\t\tcode: {type: \"string\", value: text},\n\t\t\t\t\tlanguage: {type: \"string\", value: this.match[1]}\n\t\t\t}\n\t}];\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/codeinline.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/codeinline.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/codeinline.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for code runs. For example:\n\n```\n\tThis is a `code run`.\n\tThis is another ``code run``\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"codeinline\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /(``?)/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\tvar reEnd = new RegExp(this.match[1], \"mg\");\n\t// Look for the end marker\n\treEnd.lastIndex = this.parser.pos;\n\tvar match = reEnd.exec(this.parser.source),\n\t\ttext;\n\t// Process the text\n\tif(match) {\n\t\ttext = this.parser.source.substring(this.parser.pos,match.index);\n\t\tthis.parser.pos = match.index + match[0].length;\n\t} else {\n\t\ttext = this.parser.source.substr(this.parser.pos);\n\t\tthis.parser.pos = this.parser.sourceLength;\n\t}\n\treturn [{\n\t\ttype: \"element\",\n\t\ttag: \"code\",\n\t\tchildren: [{\n\t\t\ttype: \"text\",\n\t\t\ttext: text\n\t\t}]\n\t}];\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/commentblock.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/commentblock.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/commentblock.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text block rule for HTML comments. For example:\n\n```\n<!-- This is a comment -->\n```\n\nNote that the syntax for comments is simplified to an opening \"<!--\" sequence and a closing \"-->\" sequence -- HTML itself implements a more complex format (see http://ostermiller.org/findhtmlcomment.html)\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"commentblock\";\nexports.types = {block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\tthis.matchRegExp = /<!--/mg;\n\tthis.endMatchRegExp = /-->/mg;\n};\n\nexports.findNextMatch = function(startPos) {\n\tthis.matchRegExp.lastIndex = startPos;\n\tthis.match = this.matchRegExp.exec(this.parser.source);\n\tif(this.match) {\n\t\tthis.endMatchRegExp.lastIndex = startPos + this.match[0].length;\n\t\tthis.endMatch = this.endMatchRegExp.exec(this.parser.source);\n\t\tif(this.endMatch) {\n\t\t\treturn this.match.index;\n\t\t}\n\t}\n\treturn undefined;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.endMatchRegExp.lastIndex;\n\t// Don't return any elements\n\treturn [];\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/commentinline.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/commentinline.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/commentinline.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for HTML comments. For example:\n\n```\n<!-- This is a comment -->\n```\n\nNote that the syntax for comments is simplified to an opening \"<!--\" sequence and a closing \"-->\" sequence -- HTML itself implements a more complex format (see http://ostermiller.org/findhtmlcomment.html)\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"commentinline\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\tthis.matchRegExp = /<!--/mg;\n\tthis.endMatchRegExp = /-->/mg;\n};\n\nexports.findNextMatch = function(startPos) {\n\tthis.matchRegExp.lastIndex = startPos;\n\tthis.match = this.matchRegExp.exec(this.parser.source);\n\tif(this.match) {\n\t\tthis.endMatchRegExp.lastIndex = startPos + this.match[0].length;\n\t\tthis.endMatch = this.endMatchRegExp.exec(this.parser.source);\n\t\tif(this.endMatch) {\n\t\t\treturn this.match.index;\n\t\t}\n\t}\n\treturn undefined;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.endMatchRegExp.lastIndex;\n\t// Don't return any elements\n\treturn [];\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/dash.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/dash.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/dash.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for dashes. For example:\n\n```\nThis is an en-dash: --\n\nThis is an em-dash: ---\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"dash\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /-{2,3}(?!-)/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\tvar dash = this.match[0].length === 2 ? \"–\" : \"—\";\n\treturn [{\n\t\ttype: \"entity\",\n\t\tentity: dash\n\t}];\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/emphasis/bold.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/emphasis/bold.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/emphasis/bold.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for emphasis - bold. For example:\n\n```\n\tThis is ''bold'' text\n```\n\nThis wikiparser can be modified using the rules eg:\n\n```\n\\rules except bold \n\\rules only bold \n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"bold\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /''/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\n\t// Parse the run including the terminator\n\tvar tree = this.parser.parseInlineRun(/''/mg,{eatTerminator: true});\n\n\t// Return the classed span\n\treturn [{\n\t\ttype: \"element\",\n\t\ttag: \"strong\",\n\t\tchildren: tree\n\t}];\n};\n\n})();",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/emphasis/italic.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/emphasis/italic.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/emphasis/italic.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for emphasis - italic. For example:\n\n```\n\tThis is //italic// text\n```\n\nThis wikiparser can be modified using the rules eg:\n\n```\n\\rules except italic\n\\rules only italic\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"italic\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /\\/\\//mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\n\t// Parse the run including the terminator\n\tvar tree = this.parser.parseInlineRun(/\\/\\//mg,{eatTerminator: true});\n\n\t// Return the classed span\n\treturn [{\n\t\ttype: \"element\",\n\t\ttag: \"em\",\n\t\tchildren: tree\n\t}];\n};\n\n})();",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/emphasis/strikethrough.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/emphasis/strikethrough.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/emphasis/strikethrough.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for emphasis - strikethrough. For example:\n\n```\n\tThis is ~~strikethrough~~ text\n```\n\nThis wikiparser can be modified using the rules eg:\n\n```\n\\rules except strikethrough \n\\rules only strikethrough \n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"strikethrough\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /~~/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\n\t// Parse the run including the terminator\n\tvar tree = this.parser.parseInlineRun(/~~/mg,{eatTerminator: true});\n\n\t// Return the classed span\n\treturn [{\n\t\ttype: \"element\",\n\t\ttag: \"strike\",\n\t\tchildren: tree\n\t}];\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/emphasis/subscript.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/emphasis/subscript.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/emphasis/subscript.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for emphasis - subscript. For example:\n\n```\n\tThis is ,,subscript,, text\n```\n\nThis wikiparser can be modified using the rules eg:\n\n```\n\\rules except subscript \n\\rules only subscript \n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"subscript\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /,,/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\n\t// Parse the run including the terminator\n\tvar tree = this.parser.parseInlineRun(/,,/mg,{eatTerminator: true});\n\n\t// Return the classed span\n\treturn [{\n\t\ttype: \"element\",\n\t\ttag: \"sub\",\n\t\tchildren: tree\n\t}];\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/emphasis/superscript.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/emphasis/superscript.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/emphasis/superscript.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for emphasis - superscript. For example:\n\n```\n\tThis is ^^superscript^^ text\n```\n\nThis wikiparser can be modified using the rules eg:\n\n```\n\\rules except superscript \n\\rules only superscript \n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"superscript\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /\\^\\^/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\n\t// Parse the run including the terminator\n\tvar tree = this.parser.parseInlineRun(/\\^\\^/mg,{eatTerminator: true});\n\n\t// Return the classed span\n\treturn [{\n\t\ttype: \"element\",\n\t\ttag: \"sup\",\n\t\tchildren: tree\n\t}];\n};\n\n})();",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/emphasis/underscore.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/emphasis/underscore.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/emphasis/underscore.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for emphasis - underscore. For example:\n\n```\n\tThis is __underscore__ text\n```\n\nThis wikiparser can be modified using the rules eg:\n\n```\n\\rules except underscore \n\\rules only underscore\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"underscore\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /__/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\n\t// Parse the run including the terminator\n\tvar tree = this.parser.parseInlineRun(/__/mg,{eatTerminator: true});\n\n\t// Return the classed span\n\treturn [{\n\t\ttype: \"element\",\n\t\ttag: \"u\",\n\t\tchildren: tree\n\t}];\n};\n\n})();",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/entity.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/entity.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/entity.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for HTML entities. For example:\n\n```\n\tThis is a copyright symbol: ©\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"entity\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /(&#?[a-zA-Z0-9]{2,8};)/mg;\n};\n\n/*\nParse the most recent match\n*/\nexports.parse = function() {\n\t// Get all the details of the match\n\tvar entityString = this.match[1];\n\t// Move past the macro call\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Return the entity\n\treturn [{type: \"entity\", entity: this.match[0]}];\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/extlink.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/extlink.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/extlink.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for external links. For example:\n\n```\nAn external link: https://www.tiddlywiki.com/\n\nA suppressed external link: ~http://www.tiddlyspace.com/\n```\n\nExternal links can be suppressed by preceding them with `~`.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"extlink\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /~?(?:file|http|https|mailto|ftp|irc|news|data|skype):[^\\s<>{}\\[\\]`|\"\\\\^]+(?:\\/|\\b)/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Create the link unless it is suppressed\n\tif(this.match[0].substr(0,1) === \"~\") {\n\t\treturn [{type: \"text\", text: this.match[0].substr(1)}];\n\t} else {\n\t\treturn [{\n\t\t\ttype: \"element\",\n\t\t\ttag: \"a\",\n\t\t\tattributes: {\n\t\t\t\thref: {type: \"string\", value: this.match[0]},\n\t\t\t\t\"class\": {type: \"string\", value: \"tc-tiddlylink-external\"},\n\t\t\t\ttarget: {type: \"string\", value: \"_blank\"},\n\t\t\t\trel: {type: \"string\", value: \"noopener noreferrer\"}\n\t\t\t},\n\t\t\tchildren: [{\n\t\t\t\ttype: \"text\", text: this.match[0]\n\t\t\t}]\n\t\t}];\n\t}\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/filteredtranscludeblock.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/filteredtranscludeblock.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/filteredtranscludeblock.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text rule for block-level filtered transclusion. For example:\n\n```\n{{{ [tag[docs]] }}}\n{{{ [tag[docs]] |tooltip}}}\n{{{ [tag[docs]] ||TemplateTitle}}}\n{{{ [tag[docs]] |tooltip||TemplateTitle}}}\n{{{ [tag[docs]] }}width:40;height:50;}.class.class\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"filteredtranscludeblock\";\nexports.types = {block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /\\{\\{\\{([^\\|]+?)(?:\\|([^\\|\\{\\}]+))?(?:\\|\\|([^\\|\\{\\}]+))?\\}\\}([^\\}]*)\\}(?:\\.(\\S+))?(?:\\r?\\n|$)/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Get the match details\n\tvar filter = this.match[1],\n\t\ttooltip = this.match[2],\n\t\ttemplate = $tw.utils.trim(this.match[3]),\n\t\tstyle = this.match[4],\n\t\tclasses = this.match[5];\n\t// Return the list widget\n\tvar node = {\n\t\ttype: \"list\",\n\t\tattributes: {\n\t\t\tfilter: {type: \"string\", value: filter}\n\t\t},\n\t\tisBlock: true\n\t};\n\tif(tooltip) {\n\t\tnode.attributes.tooltip = {type: \"string\", value: tooltip};\n\t}\n\tif(template) {\n\t\tnode.attributes.template = {type: \"string\", value: template};\n\t}\n\tif(style) {\n\t\tnode.attributes.style = {type: \"string\", value: style};\n\t}\n\tif(classes) {\n\t\tnode.attributes.itemClass = {type: \"string\", value: classes.split(\".\").join(\" \")};\n\t}\n\treturn [node];\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/filteredtranscludeinline.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/filteredtranscludeinline.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/filteredtranscludeinline.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text rule for inline filtered transclusion. For example:\n\n```\n{{{ [tag[docs]] }}}\n{{{ [tag[docs]] |tooltip}}}\n{{{ [tag[docs]] ||TemplateTitle}}}\n{{{ [tag[docs]] |tooltip||TemplateTitle}}}\n{{{ [tag[docs]] }}width:40;height:50;}.class.class\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"filteredtranscludeinline\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /\\{\\{\\{([^\\|]+?)(?:\\|([^\\|\\{\\}]+))?(?:\\|\\|([^\\|\\{\\}]+))?\\}\\}([^\\}]*)\\}(?:\\.(\\S+))?/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Get the match details\n\tvar filter = this.match[1],\n\t\ttooltip = this.match[2],\n\t\ttemplate = $tw.utils.trim(this.match[3]),\n\t\tstyle = this.match[4],\n\t\tclasses = this.match[5];\n\t// Return the list widget\n\tvar node = {\n\t\ttype: \"list\",\n\t\tattributes: {\n\t\t\tfilter: {type: \"string\", value: filter}\n\t\t}\n\t};\n\tif(tooltip) {\n\t\tnode.attributes.tooltip = {type: \"string\", value: tooltip};\n\t}\n\tif(template) {\n\t\tnode.attributes.template = {type: \"string\", value: template};\n\t}\n\tif(style) {\n\t\tnode.attributes.style = {type: \"string\", value: style};\n\t}\n\tif(classes) {\n\t\tnode.attributes.itemClass = {type: \"string\", value: classes.split(\".\").join(\" \")};\n\t}\n\treturn [node];\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/hardlinebreaks.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/hardlinebreaks.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/hardlinebreaks.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for marking areas with hard line breaks. For example:\n\n```\n\"\"\"\nThis is some text\nThat is set like\nIt is a Poem\nWhen it is\nClearly\nNot\n\"\"\"\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"hardlinebreaks\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /\"\"\"(?:\\r?\\n)?/mg;\n};\n\nexports.parse = function() {\n\tvar reEnd = /(\"\"\")|(\\r?\\n)/mg,\n\t\ttree = [],\n\t\tmatch;\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\tdo {\n\t\t// Parse the run up to the terminator\n\t\ttree.push.apply(tree,this.parser.parseInlineRun(reEnd,{eatTerminator: false}));\n\t\t// Redo the terminator match\n\t\treEnd.lastIndex = this.parser.pos;\n\t\tmatch = reEnd.exec(this.parser.source);\n\t\tif(match) {\n\t\t\tthis.parser.pos = reEnd.lastIndex;\n\t\t\t// Add a line break if the terminator was a line break\n\t\t\tif(match[2]) {\n\t\t\t\ttree.push({type: \"element\", tag: \"br\"});\n\t\t\t}\n\t\t}\n\t} while(match && !match[1]);\n\t// Return the nodes\n\treturn tree;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/heading.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/heading.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/heading.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text block rule for headings\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"heading\";\nexports.types = {block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /(!{1,6})/mg;\n};\n\n/*\nParse the most recent match\n*/\nexports.parse = function() {\n\t// Get all the details of the match\n\tvar headingLevel = this.match[1].length;\n\t// Move past the !s\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Parse any classes, whitespace and then the heading itself\n\tvar classes = this.parser.parseClasses();\n\tthis.parser.skipWhitespace({treatNewlinesAsNonWhitespace: true});\n\tvar tree = this.parser.parseInlineRun(/(\\r?\\n)/mg);\n\t// Return the heading\n\treturn [{\n\t\ttype: \"element\",\n\t\ttag: \"h\" + headingLevel, \n\t\tattributes: {\n\t\t\t\"class\": {type: \"string\", value: classes.join(\" \")}\n\t\t},\n\t\tchildren: tree\n\t}];\n};\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/horizrule.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/horizrule.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/horizrule.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text block rule for rules. For example:\n\n```\n---\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"horizrule\";\nexports.types = {block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /-{3,}\\r?(?:\\n|$)/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\treturn [{type: \"element\", tag: \"hr\"}];\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/html.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/html.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/html.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki rule for HTML elements and widgets. For example:\n\n{{{\n<aside>\nThis is an HTML5 aside element\n</aside>\n\n<$slider target=\"MyTiddler\">\nThis is a widget invocation\n</$slider>\n\n}}}\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"html\";\nexports.types = {inline: true, block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n};\n\nexports.findNextMatch = function(startPos) {\n\t// Find the next tag\n\tthis.nextTag = this.findNextTag(this.parser.source,startPos,{\n\t\trequireLineBreak: this.is.block\n\t});\n\treturn this.nextTag ? this.nextTag.start : undefined;\n};\n\n/*\nParse the most recent match\n*/\nexports.parse = function() {\n\t// Retrieve the most recent match so that recursive calls don't overwrite it\n\tvar tag = this.nextTag;\n\tthis.nextTag = null;\n\t// Advance the parser position to past the tag\n\tthis.parser.pos = tag.end;\n\t// Check for an immediately following double linebreak\n\tvar hasLineBreak = !tag.isSelfClosing && !!$tw.utils.parseTokenRegExp(this.parser.source,this.parser.pos,/([^\\S\\n\\r]*\\r?\\n(?:[^\\S\\n\\r]*\\r?\\n|$))/g);\n\t// Set whether we're in block mode\n\ttag.isBlock = this.is.block || hasLineBreak;\n\t// Parse the body if we need to\n\tif(!tag.isSelfClosing && $tw.config.htmlVoidElements.indexOf(tag.tag) === -1) {\n\t\t\tvar reEndString = \"</\" + $tw.utils.escapeRegExp(tag.tag) + \">\",\n\t\t\t\treEnd = new RegExp(\"(\" + reEndString + \")\",\"mg\");\n\t\tif(hasLineBreak) {\n\t\t\ttag.children = this.parser.parseBlocks(reEndString);\n\t\t} else {\n\t\t\ttag.children = this.parser.parseInlineRun(reEnd);\n\t\t}\n\t\treEnd.lastIndex = this.parser.pos;\n\t\tvar endMatch = reEnd.exec(this.parser.source);\n\t\tif(endMatch && endMatch.index === this.parser.pos) {\n\t\t\tthis.parser.pos = endMatch.index + endMatch[0].length;\n\t\t}\n\t}\n\t// Return the tag\n\treturn [tag];\n};\n\n/*\nLook for an HTML tag. Returns null if not found, otherwise returns {type: \"element\", name:, attributes: [], isSelfClosing:, start:, end:,}\n*/\nexports.parseTag = function(source,pos,options) {\n\toptions = options || {};\n\tvar token,\n\t\tnode = {\n\t\t\ttype: \"element\",\n\t\t\tstart: pos,\n\t\t\tattributes: {}\n\t\t};\n\t// Define our regexps\n\tvar reTagName = /([a-zA-Z0-9\\-\\$]+)/g;\n\t// Skip whitespace\n\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t// Look for a less than sign\n\ttoken = $tw.utils.parseTokenString(source,pos,\"<\");\n\tif(!token) {\n\t\treturn null;\n\t}\n\tpos = token.end;\n\t// Get the tag name\n\ttoken = $tw.utils.parseTokenRegExp(source,pos,reTagName);\n\tif(!token) {\n\t\treturn null;\n\t}\n\tnode.tag = token.match[1];\n\tif(node.tag.slice(1).indexOf(\"$\") !== -1) {\n\t\treturn null;\n\t}\n\tif(node.tag.charAt(0) === \"$\") {\n\t\tnode.type = node.tag.substr(1);\n\t}\n\tpos = token.end;\n\t// Check that the tag is terminated by a space, / or >\n\tif(!$tw.utils.parseWhiteSpace(source,pos) && !(source.charAt(pos) === \"/\") && !(source.charAt(pos) === \">\") ) {\n\t\treturn null;\n\t}\n\t// Process attributes\n\tvar attribute = $tw.utils.parseAttribute(source,pos);\n\twhile(attribute) {\n\t\tnode.attributes[attribute.name] = attribute;\n\t\tpos = attribute.end;\n\t\t// Get the next attribute\n\t\tattribute = $tw.utils.parseAttribute(source,pos);\n\t}\n\t// Skip whitespace\n\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t// Look for a closing slash\n\ttoken = $tw.utils.parseTokenString(source,pos,\"/\");\n\tif(token) {\n\t\tpos = token.end;\n\t\tnode.isSelfClosing = true;\n\t}\n\t// Look for a greater than sign\n\ttoken = $tw.utils.parseTokenString(source,pos,\">\");\n\tif(!token) {\n\t\treturn null;\n\t}\n\tpos = token.end;\n\t// Check for a required line break\n\tif(options.requireLineBreak) {\n\t\ttoken = $tw.utils.parseTokenRegExp(source,pos,/([^\\S\\n\\r]*\\r?\\n(?:[^\\S\\n\\r]*\\r?\\n|$))/g);\n\t\tif(!token) {\n\t\t\treturn null;\n\t\t}\n\t}\n\t// Update the end position\n\tnode.end = pos;\n\treturn node;\n};\n\nexports.findNextTag = function(source,pos,options) {\n\t// A regexp for finding candidate HTML tags\n\tvar reLookahead = /<([a-zA-Z\\-\\$]+)/g;\n\t// Find the next candidate\n\treLookahead.lastIndex = pos;\n\tvar match = reLookahead.exec(source);\n\twhile(match) {\n\t\t// Try to parse the candidate as a tag\n\t\tvar tag = this.parseTag(source,match.index,options);\n\t\t// Return success\n\t\tif(tag && this.isLegalTag(tag)) {\n\t\t\treturn tag;\n\t\t}\n\t\t// Look for the next match\n\t\treLookahead.lastIndex = match.index + 1;\n\t\tmatch = reLookahead.exec(source);\n\t}\n\t// Failed\n\treturn null;\n};\n\nexports.isLegalTag = function(tag) {\n\t// Widgets are always OK\n\tif(tag.type !== \"element\") {\n\t\treturn true;\n\t// If it's an HTML tag that starts with a dash then it's not legal\n\t} else if(tag.tag.charAt(0) === \"-\") {\n\t\treturn false;\n\t} else {\n\t\t// Otherwise it's OK\n\t\treturn true;\n\t}\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/image.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/image.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/image.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for embedding images. For example:\n\n```\n[img[https://tiddlywiki.com/fractalveg.jpg]]\n[img width=23 height=24 [https://tiddlywiki.com/fractalveg.jpg]]\n[img width={{!!width}} height={{!!height}} [https://tiddlywiki.com/fractalveg.jpg]]\n[img[Description of image|https://tiddlywiki.com/fractalveg.jpg]]\n[img[TiddlerTitle]]\n[img[Description of image|TiddlerTitle]]\n```\n\nGenerates the `<$image>` widget.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"image\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n};\n\nexports.findNextMatch = function(startPos) {\n\t// Find the next tag\n\tthis.nextImage = this.findNextImage(this.parser.source,startPos);\n\treturn this.nextImage ? this.nextImage.start : undefined;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.nextImage.end;\n\tvar node = {\n\t\ttype: \"image\",\n\t\tattributes: this.nextImage.attributes\n\t};\n\treturn [node];\n};\n\n/*\nFind the next image from the current position\n*/\nexports.findNextImage = function(source,pos) {\n\t// A regexp for finding candidate HTML tags\n\tvar reLookahead = /(\\[img)/g;\n\t// Find the next candidate\n\treLookahead.lastIndex = pos;\n\tvar match = reLookahead.exec(source);\n\twhile(match) {\n\t\t// Try to parse the candidate as a tag\n\t\tvar tag = this.parseImage(source,match.index);\n\t\t// Return success\n\t\tif(tag) {\n\t\t\treturn tag;\n\t\t}\n\t\t// Look for the next match\n\t\treLookahead.lastIndex = match.index + 1;\n\t\tmatch = reLookahead.exec(source);\n\t}\n\t// Failed\n\treturn null;\n};\n\n/*\nLook for an image at the specified position. Returns null if not found, otherwise returns {type: \"image\", attributes: [], isSelfClosing:, start:, end:,}\n*/\nexports.parseImage = function(source,pos) {\n\tvar token,\n\t\tnode = {\n\t\t\ttype: \"image\",\n\t\t\tstart: pos,\n\t\t\tattributes: {}\n\t\t};\n\t// Skip whitespace\n\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t// Look for the `[img`\n\ttoken = $tw.utils.parseTokenString(source,pos,\"[img\");\n\tif(!token) {\n\t\treturn null;\n\t}\n\tpos = token.end;\n\t// Skip whitespace\n\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t// Process attributes\n\tif(source.charAt(pos) !== \"[\") {\n\t\tvar attribute = $tw.utils.parseAttribute(source,pos);\n\t\twhile(attribute) {\n\t\t\tnode.attributes[attribute.name] = attribute;\n\t\t\tpos = attribute.end;\n\t\t\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t\t\tif(source.charAt(pos) !== \"[\") {\n\t\t\t\t// Get the next attribute\n\t\t\t\tattribute = $tw.utils.parseAttribute(source,pos);\n\t\t\t} else {\n\t\t\t\tattribute = null;\n\t\t\t}\n\t\t}\n\t}\n\t// Skip whitespace\n\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t// Look for the `[` after the attributes\n\ttoken = $tw.utils.parseTokenString(source,pos,\"[\");\n\tif(!token) {\n\t\treturn null;\n\t}\n\tpos = token.end;\n\t// Skip whitespace\n\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t// Get the source up to the terminating `]]`\n\ttoken = $tw.utils.parseTokenRegExp(source,pos,/(?:([^|\\]]*?)\\|)?([^\\]]+?)\\]\\]/g);\n\tif(!token) {\n\t\treturn null;\n\t}\n\tpos = token.end;\n\tif(token.match[1]) {\n\t\tnode.attributes.tooltip = {type: \"string\", value: token.match[1].trim()};\n\t}\n\tnode.attributes.source = {type: \"string\", value: (token.match[2] || \"\").trim()};\n\t// Update the end position\n\tnode.end = pos;\n\treturn node;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/import.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/import.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/import.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki pragma rule for importing variable definitions\n\n```\n\\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"import\";\nexports.types = {pragma: true};\n\n/*\nInstantiate parse rule\n*/\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /^\\\\import[^\\S\\n]/mg;\n};\n\n/*\nParse the most recent match\n*/\nexports.parse = function() {\n\tvar self = this;\n\t// Move past the pragma invocation\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Parse the filter terminated by a line break\n\tvar reMatch = /(.*)(\\r?\\n)|$/mg;\n\treMatch.lastIndex = this.parser.pos;\n\tvar match = reMatch.exec(this.parser.source);\n\tthis.parser.pos = reMatch.lastIndex;\n\t// Parse tree nodes to return\n\treturn [{\n\t\ttype: \"importvariables\",\n\t\tattributes: {\n\t\t\tfilter: {type: \"string\", value: match[1]}\n\t\t},\n\t\tchildren: []\n\t}];\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/list.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/list.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/list.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text block rule for lists. For example:\n\n```\n* This is an unordered list\n* It has two items\n\n# This is a numbered list\n## With a subitem\n# And a third item\n\n; This is a term that is being defined\n: This is the definition of that term\n```\n\nNote that lists can be nested arbitrarily:\n\n```\n#** One\n#* Two\n#** Three\n#**** Four\n#**# Five\n#**## Six\n## Seven\n### Eight\n## Nine\n```\n\nA CSS class can be applied to a list item as follows:\n\n```\n* List item one\n*.active List item two has the class `active`\n* List item three\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"list\";\nexports.types = {block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /([\\*#;:>]+)/mg;\n};\n\nvar listTypes = {\n\t\"*\": {listTag: \"ul\", itemTag: \"li\"},\n\t\"#\": {listTag: \"ol\", itemTag: \"li\"},\n\t\";\": {listTag: \"dl\", itemTag: \"dt\"},\n\t\":\": {listTag: \"dl\", itemTag: \"dd\"},\n\t\">\": {listTag: \"blockquote\", itemTag: \"p\"}\n};\n\n/*\nParse the most recent match\n*/\nexports.parse = function() {\n\t// Array of parse tree nodes for the previous row of the list\n\tvar listStack = [];\n\t// Cycle through the items in the list\n\twhile(true) {\n\t\t// Match the list marker\n\t\tvar reMatch = /([\\*#;:>]+)/mg;\n\t\treMatch.lastIndex = this.parser.pos;\n\t\tvar match = reMatch.exec(this.parser.source);\n\t\tif(!match || match.index !== this.parser.pos) {\n\t\t\tbreak;\n\t\t}\n\t\t// Check whether the list type of the top level matches\n\t\tvar listInfo = listTypes[match[0].charAt(0)];\n\t\tif(listStack.length > 0 && listStack[0].tag !== listInfo.listTag) {\n\t\t\tbreak;\n\t\t}\n\t\t// Move past the list marker\n\t\tthis.parser.pos = match.index + match[0].length;\n\t\t// Walk through the list markers for the current row\n\t\tfor(var t=0; t<match[0].length; t++) {\n\t\t\tlistInfo = listTypes[match[0].charAt(t)];\n\t\t\t// Remove any stacked up element if we can't re-use it because the list type doesn't match\n\t\t\tif(listStack.length > t && listStack[t].tag !== listInfo.listTag) {\n\t\t\t\tlistStack.splice(t,listStack.length - t);\n\t\t\t}\n\t\t\t// Construct the list element or reuse the previous one at this level\n\t\t\tif(listStack.length <= t) {\n\t\t\t\tvar listElement = {type: \"element\", tag: listInfo.listTag, children: [\n\t\t\t\t\t{type: \"element\", tag: listInfo.itemTag, children: []}\n\t\t\t\t]};\n\t\t\t\t// Link this list element into the last child item of the parent list item\n\t\t\t\tif(t) {\n\t\t\t\t\tvar prevListItem = listStack[t-1].children[listStack[t-1].children.length-1];\n\t\t\t\t\tprevListItem.children.push(listElement);\n\t\t\t\t}\n\t\t\t\t// Save this element in the stack\n\t\t\t\tlistStack[t] = listElement;\n\t\t\t} else if(t === (match[0].length - 1)) {\n\t\t\t\tlistStack[t].children.push({type: \"element\", tag: listInfo.itemTag, children: []});\n\t\t\t}\n\t\t}\n\t\tif(listStack.length > match[0].length) {\n\t\t\tlistStack.splice(match[0].length,listStack.length - match[0].length);\n\t\t}\n\t\t// Process the body of the list item into the last list item\n\t\tvar lastListChildren = listStack[listStack.length-1].children,\n\t\t\tlastListItem = lastListChildren[lastListChildren.length-1],\n\t\t\tclasses = this.parser.parseClasses();\n\t\tthis.parser.skipWhitespace({treatNewlinesAsNonWhitespace: true});\n\t\tvar tree = this.parser.parseInlineRun(/(\\r?\\n)/mg);\n\t\tlastListItem.children.push.apply(lastListItem.children,tree);\n\t\tif(classes.length > 0) {\n\t\t\t$tw.utils.addClassToParseTreeNode(lastListItem,classes.join(\" \"));\n\t\t}\n\t\t// Consume any whitespace following the list item\n\t\tthis.parser.skipWhitespace();\n\t}\n\t// Return the root element of the list\n\treturn [listStack[0]];\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/macrocallblock.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/macrocallblock.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/macrocallblock.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki rule for block macro calls\n\n```\n<<name value value2>>\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"macrocallblock\";\nexports.types = {block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /<<([^>\\s]+)(?:\\s*)((?:[^>]|(?:>(?!>)))*?)>>(?:\\r?\\n|$)/mg;\n};\n\n/*\nParse the most recent match\n*/\nexports.parse = function() {\n\t// Get all the details of the match\n\tvar macroName = this.match[1],\n\t\tparamString = this.match[2];\n\t// Move past the macro call\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\tvar params = [],\n\t\treParam = /\\s*(?:([A-Za-z0-9\\-_]+)\\s*:)?(?:\\s*(?:\"\"\"([\\s\\S]*?)\"\"\"|\"([^\"]*)\"|'([^']*)'|\\[\\[([^\\]]*)\\]\\]|([^\"'\\s]+)))/mg,\n\t\tparamMatch = reParam.exec(paramString);\n\twhile(paramMatch) {\n\t\t// Process this parameter\n\t\tvar paramInfo = {\n\t\t\tvalue: paramMatch[2] || paramMatch[3] || paramMatch[4] || paramMatch[5] || paramMatch[6]\n\t\t};\n\t\tif(paramMatch[1]) {\n\t\t\tparamInfo.name = paramMatch[1];\n\t\t}\n\t\tparams.push(paramInfo);\n\t\t// Find the next match\n\t\tparamMatch = reParam.exec(paramString);\n\t}\n\treturn [{\n\t\ttype: \"macrocall\",\n\t\tname: macroName,\n\t\tparams: params,\n\t\tisBlock: true\n\t}];\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/macrocallinline.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/macrocallinline.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/macrocallinline.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki rule for macro calls\n\n```\n<<name value value2>>\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"macrocallinline\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /<<([^\\s>]+)\\s*([\\s\\S]*?)>>/mg;\n};\n\n/*\nParse the most recent match\n*/\nexports.parse = function() {\n\t// Get all the details of the match\n\tvar macroName = this.match[1],\n\t\tparamString = this.match[2];\n\t// Move past the macro call\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\tvar params = [],\n\t\treParam = /\\s*(?:([A-Za-z0-9\\-_]+)\\s*:)?(?:\\s*(?:\"\"\"([\\s\\S]*?)\"\"\"|\"([^\"]*)\"|'([^']*)'|\\[\\[([^\\]]*)\\]\\]|([^\"'\\s]+)))/mg,\n\t\tparamMatch = reParam.exec(paramString);\n\twhile(paramMatch) {\n\t\t// Process this parameter\n\t\tvar paramInfo = {\n\t\t\tvalue: paramMatch[2] || paramMatch[3] || paramMatch[4] || paramMatch[5]|| paramMatch[6]\n\t\t};\n\t\tif(paramMatch[1]) {\n\t\t\tparamInfo.name = paramMatch[1];\n\t\t}\n\t\tparams.push(paramInfo);\n\t\t// Find the next match\n\t\tparamMatch = reParam.exec(paramString);\n\t}\n\treturn [{\n\t\ttype: \"macrocall\",\n\t\tname: macroName,\n\t\tparams: params\n\t}];\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/macrodef.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/macrodef.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/macrodef.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki pragma rule for macro definitions\n\n```\n\\define name(param:defaultvalue,param2:defaultvalue)\ndefinition text, including $param$ markers\n\\end\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"macrodef\";\nexports.types = {pragma: true};\n\n/*\nInstantiate parse rule\n*/\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /^\\\\define\\s+([^(\\s]+)\\(\\s*([^)]*)\\)(\\s*\\r?\\n)?/mg;\n};\n\n/*\nParse the most recent match\n*/\nexports.parse = function() {\n\t// Move past the macro name and parameters\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Parse the parameters\n\tvar paramString = this.match[2],\n\t\tparams = [];\n\tif(paramString !== \"\") {\n\t\tvar reParam = /\\s*([A-Za-z0-9\\-_]+)(?:\\s*:\\s*(?:\"\"\"([\\s\\S]*?)\"\"\"|\"([^\"]*)\"|'([^']*)'|\\[\\[([^\\]]*)\\]\\]|([^\"'\\s]+)))?/mg,\n\t\t\tparamMatch = reParam.exec(paramString);\n\t\twhile(paramMatch) {\n\t\t\t// Save the parameter details\n\t\t\tvar paramInfo = {name: paramMatch[1]},\n\t\t\t\tdefaultValue = paramMatch[2] || paramMatch[3] || paramMatch[4] || paramMatch[5] || paramMatch[6];\n\t\t\tif(defaultValue) {\n\t\t\t\tparamInfo[\"default\"] = defaultValue;\n\t\t\t}\n\t\t\tparams.push(paramInfo);\n\t\t\t// Look for the next parameter\n\t\t\tparamMatch = reParam.exec(paramString);\n\t\t}\n\t}\n\t// Is this a multiline definition?\n\tvar reEnd;\n\tif(this.match[3]) {\n\t\t// If so, the end of the body is marked with \\end\n\t\treEnd = /(\\r?\\n\\\\end[^\\S\\n\\r]*(?:$|\\r?\\n))/mg;\n\t} else {\n\t\t// Otherwise, the end of the definition is marked by the end of the line\n\t\treEnd = /($|\\r?\\n)/mg;\n\t\t// Move past any whitespace\n\t\tthis.parser.pos = $tw.utils.skipWhiteSpace(this.parser.source,this.parser.pos);\n\t}\n\t// Find the end of the definition\n\treEnd.lastIndex = this.parser.pos;\n\tvar text,\n\t\tendMatch = reEnd.exec(this.parser.source);\n\tif(endMatch) {\n\t\ttext = this.parser.source.substring(this.parser.pos,endMatch.index);\n\t\tthis.parser.pos = endMatch.index + endMatch[0].length;\n\t} else {\n\t\t// We didn't find the end of the definition, so we'll make it blank\n\t\ttext = \"\";\n\t}\n\t// Save the macro definition\n\treturn [{\n\t\ttype: \"set\",\n\t\tattributes: {\n\t\t\tname: {type: \"string\", value: this.match[1]},\n\t\t\tvalue: {type: \"string\", value: text}\n\t\t},\n\t\tchildren: [],\n\t\tparams: params,\n\t\tisMacroDefinition: true\n\t}];\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/prettyextlink.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/prettyextlink.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/prettyextlink.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for external links. For example:\n\n```\n[ext[https://tiddlywiki.com/fractalveg.jpg]]\n[ext[Tooltip|https://tiddlywiki.com/fractalveg.jpg]]\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"prettyextlink\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n};\n\nexports.findNextMatch = function(startPos) {\n\t// Find the next tag\n\tthis.nextLink = this.findNextLink(this.parser.source,startPos);\n\treturn this.nextLink ? this.nextLink.start : undefined;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.nextLink.end;\n\treturn [this.nextLink];\n};\n\n/*\nFind the next link from the current position\n*/\nexports.findNextLink = function(source,pos) {\n\t// A regexp for finding candidate links\n\tvar reLookahead = /(\\[ext\\[)/g;\n\t// Find the next candidate\n\treLookahead.lastIndex = pos;\n\tvar match = reLookahead.exec(source);\n\twhile(match) {\n\t\t// Try to parse the candidate as a link\n\t\tvar link = this.parseLink(source,match.index);\n\t\t// Return success\n\t\tif(link) {\n\t\t\treturn link;\n\t\t}\n\t\t// Look for the next match\n\t\treLookahead.lastIndex = match.index + 1;\n\t\tmatch = reLookahead.exec(source);\n\t}\n\t// Failed\n\treturn null;\n};\n\n/*\nLook for an link at the specified position. Returns null if not found, otherwise returns {type: \"element\", tag: \"a\", attributes: [], isSelfClosing:, start:, end:,}\n*/\nexports.parseLink = function(source,pos) {\n\tvar token,\n\t\ttextNode = {\n\t\t\ttype: \"text\"\n\t\t},\n\t\tnode = {\n\t\t\ttype: \"element\",\n\t\t\ttag: \"a\",\n\t\t\tstart: pos,\n\t\t\tattributes: {\n\t\t\t\t\"class\": {type: \"string\", value: \"tc-tiddlylink-external\"},\n\t\t\t},\n\t\t\tchildren: [textNode]\n\t\t};\n\t// Skip whitespace\n\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t// Look for the `[ext[`\n\ttoken = $tw.utils.parseTokenString(source,pos,\"[ext[\");\n\tif(!token) {\n\t\treturn null;\n\t}\n\tpos = token.end;\n\t// Look ahead for the terminating `]]`\n\tvar closePos = source.indexOf(\"]]\",pos);\n\tif(closePos === -1) {\n\t\treturn null;\n\t}\n\t// Look for a `|` separating the tooltip\n\tvar splitPos = source.indexOf(\"|\",pos);\n\tif(splitPos === -1 || splitPos > closePos) {\n\t\tsplitPos = null;\n\t}\n\t// Pull out the tooltip and URL\n\tvar tooltip, URL;\n\tif(splitPos) {\n\t\tURL = source.substring(splitPos + 1,closePos).trim();\n\t\ttextNode.text = source.substring(pos,splitPos).trim();\n\t} else {\n\t\tURL = source.substring(pos,closePos).trim();\n\t\ttextNode.text = URL;\n\t}\n\tnode.attributes.href = {type: \"string\", value: URL};\n\tnode.attributes.target = {type: \"string\", value: \"_blank\"};\n\tnode.attributes.rel = {type: \"string\", value: \"noopener noreferrer\"};\n\t// Update the end position\n\tnode.end = closePos + 2;\n\treturn node;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/prettylink.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/prettylink.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/prettylink.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for pretty links. For example:\n\n```\n[[Introduction]]\n\n[[Link description|TiddlerTitle]]\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"prettylink\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /\\[\\[(.*?)(?:\\|(.*?))?\\]\\]/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Process the link\n\tvar text = this.match[1],\n\t\tlink = this.match[2] || text;\n\tif($tw.utils.isLinkExternal(link)) {\n\t\treturn [{\n\t\t\ttype: \"element\",\n\t\t\ttag: \"a\",\n\t\t\tattributes: {\n\t\t\t\thref: {type: \"string\", value: link},\n\t\t\t\t\"class\": {type: \"string\", value: \"tc-tiddlylink-external\"},\n\t\t\t\ttarget: {type: \"string\", value: \"_blank\"},\n\t\t\t\trel: {type: \"string\", value: \"noopener noreferrer\"}\n\t\t\t},\n\t\t\tchildren: [{\n\t\t\t\ttype: \"text\", text: text\n\t\t\t}]\n\t\t}];\n\t} else {\n\t\treturn [{\n\t\t\ttype: \"link\",\n\t\t\tattributes: {\n\t\t\t\tto: {type: \"string\", value: link}\n\t\t\t},\n\t\t\tchildren: [{\n\t\t\t\ttype: \"text\", text: text\n\t\t\t}]\n\t\t}];\n\t}\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/quoteblock.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/quoteblock.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/quoteblock.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text rule for quote blocks. For example:\n\n```\n\t<<<.optionalClass(es) optional cited from\n\ta quote\n\t<<<\n\t\n\t<<<.optionalClass(es)\n\ta quote\n\t<<< optional cited from\n```\n\nQuotes can be quoted by putting more <s\n\n```\n\t<<<\n\tQuote Level 1\n\t\n\t<<<<\n\tQuoteLevel 2\n\t<<<<\n\t\n\t<<<\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"quoteblock\";\nexports.types = {block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /(<<<+)/mg;\n};\n\nexports.parse = function() {\n\tvar classes = [\"tc-quote\"];\n\t// Get all the details of the match\n\tvar reEndString = \"^\" + this.match[1] + \"(?!<)\";\n\t// Move past the <s\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t\n\t// Parse any classes, whitespace and then the optional cite itself\n\tclasses.push.apply(classes, this.parser.parseClasses());\n\tthis.parser.skipWhitespace({treatNewlinesAsNonWhitespace: true});\n\tvar cite = this.parser.parseInlineRun(/(\\r?\\n)/mg);\n\t// before handling the cite, parse the body of the quote\n\tvar tree= this.parser.parseBlocks(reEndString);\n\t// If we got a cite, put it before the text\n\tif(cite.length > 0) {\n\t\ttree.unshift({\n\t\t\ttype: \"element\",\n\t\t\ttag: \"cite\",\n\t\t\tchildren: cite\n\t\t});\n\t}\n\t// Parse any optional cite\n\tthis.parser.skipWhitespace({treatNewlinesAsNonWhitespace: true});\n\tcite = this.parser.parseInlineRun(/(\\r?\\n)/mg);\n\t// If we got a cite, push it\n\tif(cite.length > 0) {\n\t\ttree.push({\n\t\t\ttype: \"element\",\n\t\t\ttag: \"cite\",\n\t\t\tchildren: cite\n\t\t});\n\t}\n\t// Return the blockquote element\n\treturn [{\n\t\ttype: \"element\",\n\t\ttag: \"blockquote\",\n\t\tattributes: {\n\t\t\tclass: { type: \"string\", value: classes.join(\" \") },\n\t\t},\n\t\tchildren: tree\n\t}];\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/rules.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/rules.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/rules.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki pragma rule for rules specifications\n\n```\n\\rules except ruleone ruletwo rulethree\n\\rules only ruleone ruletwo rulethree\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"rules\";\nexports.types = {pragma: true};\n\n/*\nInstantiate parse rule\n*/\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /^\\\\rules[^\\S\\n]/mg;\n};\n\n/*\nParse the most recent match\n*/\nexports.parse = function() {\n\t// Move past the pragma invocation\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Parse whitespace delimited tokens terminated by a line break\n\tvar reMatch = /[^\\S\\n]*(\\S+)|(\\r?\\n)/mg,\n\t\ttokens = [];\n\treMatch.lastIndex = this.parser.pos;\n\tvar match = reMatch.exec(this.parser.source);\n\twhile(match && match.index === this.parser.pos) {\n\t\tthis.parser.pos = reMatch.lastIndex;\n\t\t// Exit if we've got the line break\n\t\tif(match[2]) {\n\t\t\tbreak;\n\t\t}\n\t\t// Process the token\n\t\tif(match[1]) {\n\t\t\ttokens.push(match[1]);\n\t\t}\n\t\t// Match the next token\n\t\tmatch = reMatch.exec(this.parser.source);\n\t}\n\t// Process the tokens\n\tif(tokens.length > 0) {\n\t\tthis.parser.amendRules(tokens[0],tokens.slice(1));\n\t}\n\t// No parse tree nodes to return\n\treturn [];\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/styleblock.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/styleblock.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/styleblock.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text block rule for assigning styles and classes to paragraphs and other blocks. For example:\n\n```\n@@.myClass\n@@background-color:red;\nThis paragraph will have the CSS class `myClass`.\n\n* The `<ul>` around this list will also have the class `myClass`\n* List item 2\n\n@@\n```\n\nNote that classes and styles can be mixed subject to the rule that styles must precede classes. For example\n\n```\n@@.myFirstClass.mySecondClass\n@@width:100px;.myThirdClass\nThis is a paragraph\n@@\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"styleblock\";\nexports.types = {block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /@@((?:[^\\.\\r\\n\\s:]+:[^\\r\\n;]+;)+)?(?:\\.([^\\r\\n\\s]+))?\\r?\\n/mg;\n};\n\nexports.parse = function() {\n\tvar reEndString = \"^@@(?:\\\\r?\\\\n)?\";\n\tvar classes = [], styles = [];\n\tdo {\n\t\t// Get the class and style\n\t\tif(this.match[1]) {\n\t\t\tstyles.push(this.match[1]);\n\t\t}\n\t\tif(this.match[2]) {\n\t\t\tclasses.push(this.match[2].split(\".\").join(\" \"));\n\t\t}\n\t\t// Move past the match\n\t\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t\t// Look for another line of classes and styles\n\t\tthis.match = this.matchRegExp.exec(this.parser.source);\n\t} while(this.match && this.match.index === this.parser.pos);\n\t// Parse the body\n\tvar tree = this.parser.parseBlocks(reEndString);\n\tfor(var t=0; t<tree.length; t++) {\n\t\tif(classes.length > 0) {\n\t\t\t$tw.utils.addClassToParseTreeNode(tree[t],classes.join(\" \"));\n\t\t}\n\t\tif(styles.length > 0) {\n\t\t\t$tw.utils.addAttributeToParseTreeNode(tree[t],\"style\",styles.join(\"\"));\n\t\t}\n\t}\n\treturn tree;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/styleinline.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/styleinline.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/styleinline.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for assigning styles and classes to inline runs. For example:\n\n```\n@@.myClass This is some text with a class@@\n@@background-color:red;This is some text with a background colour@@\n@@width:100px;.myClass This is some text with a class and a width@@\n```\n\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"styleinline\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /@@((?:[^\\.\\r\\n\\s:]+:[^\\r\\n;]+;)+)?(\\.(?:[^\\r\\n\\s]+)\\s+)?/mg;\n};\n\nexports.parse = function() {\n\tvar reEnd = /@@/g;\n\t// Get the styles and class\n\tvar stylesString = this.match[1],\n\t\tclassString = this.match[2] ? this.match[2].split(\".\").join(\" \") : undefined;\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Parse the run up to the terminator\n\tvar tree = this.parser.parseInlineRun(reEnd,{eatTerminator: true});\n\t// Return the classed span\n\tvar node = {\n\t\ttype: \"element\",\n\t\ttag: \"span\",\n\t\tattributes: {\n\t\t\t\"class\": {type: \"string\", value: \"tc-inline-style\"}\n\t\t},\n\t\tchildren: tree\n\t};\n\tif(classString) {\n\t\t$tw.utils.addClassToParseTreeNode(node,classString);\n\t}\n\tif(stylesString) {\n\t\t$tw.utils.addAttributeToParseTreeNode(node,\"style\",stylesString);\n\t}\n\treturn [node];\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/syslink.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/syslink.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/syslink.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for system tiddler links.\nCan be suppressed preceding them with `~`.\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"syslink\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = new RegExp(\n\t\t\"~?\\\\$:\\\\/[\" +\n\t\t$tw.config.textPrimitives.anyLetter.substr(1,$tw.config.textPrimitives.anyLetter.length - 2) +\n\t\t\"\\/._-]+\",\n\t\t\"mg\"\n\t);\n};\n\nexports.parse = function() {\n\tvar match = this.match[0];\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Create the link unless it is suppressed\n\tif(match.substr(0,1) === \"~\") {\n\t\treturn [{type: \"text\", text: match.substr(1)}];\n\t} else {\n\t\treturn [{\n\t\t\ttype: \"link\",\n\t\t\tattributes: {\n\t\t\t\tto: {type: \"string\", value: match}\n\t\t\t},\n\t\t\tchildren: [{\n\t\t\t\ttype: \"text\",\n\t\t\t\ttext: match\n\t\t\t}]\n\t\t}];\n\t}\n};\n\n})();",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/table.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/table.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/table.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text block rule for tables.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"table\";\nexports.types = {block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /^\\|(?:[^\\n]*)\\|(?:[fhck]?)\\r?(?:\\n|$)/mg;\n};\n\nvar processRow = function(prevColumns) {\n\tvar cellRegExp = /(?:\\|([^\\n\\|]*)\\|)|(\\|[fhck]?\\r?(?:\\n|$))/mg,\n\t\tcellTermRegExp = /((?:\\x20*)\\|)/mg,\n\t\ttree = [],\n\t\tcol = 0,\n\t\tcolSpanCount = 1,\n\t\tprevCell,\n\t\tvAlign;\n\t// Match a single cell\n\tcellRegExp.lastIndex = this.parser.pos;\n\tvar cellMatch = cellRegExp.exec(this.parser.source);\n\twhile(cellMatch && cellMatch.index === this.parser.pos) {\n\t\tif(cellMatch[1] === \"~\") {\n\t\t\t// Rowspan\n\t\t\tvar last = prevColumns[col];\n\t\t\tif(last) {\n\t\t\t\tlast.rowSpanCount++;\n\t\t\t\t$tw.utils.addAttributeToParseTreeNode(last.element,\"rowspan\",last.rowSpanCount);\n\t\t\t\tvAlign = $tw.utils.getAttributeValueFromParseTreeNode(last.element,\"valign\",\"center\");\n\t\t\t\t$tw.utils.addAttributeToParseTreeNode(last.element,\"valign\",vAlign);\n\t\t\t\tif(colSpanCount > 1) {\n\t\t\t\t\t$tw.utils.addAttributeToParseTreeNode(last.element,\"colspan\",colSpanCount);\n\t\t\t\t\tcolSpanCount = 1;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Move to just before the `|` terminating the cell\n\t\t\tthis.parser.pos = cellRegExp.lastIndex - 1;\n\t\t} else if(cellMatch[1] === \">\") {\n\t\t\t// Colspan\n\t\t\tcolSpanCount++;\n\t\t\t// Move to just before the `|` terminating the cell\n\t\t\tthis.parser.pos = cellRegExp.lastIndex - 1;\n\t\t} else if(cellMatch[1] === \"<\" && prevCell) {\n\t\t\tcolSpanCount = 1 + $tw.utils.getAttributeValueFromParseTreeNode(prevCell,\"colspan\",1);\n\t\t\t$tw.utils.addAttributeToParseTreeNode(prevCell,\"colspan\",colSpanCount);\n\t\t\tcolSpanCount = 1;\n\t\t\t// Move to just before the `|` terminating the cell\n\t\t\tthis.parser.pos = cellRegExp.lastIndex - 1;\n\t\t} else if(cellMatch[2]) {\n\t\t\t// End of row\n\t\t\tif(prevCell && colSpanCount > 1) {\n\t\t\t\tif(prevCell.attributes && prevCell.attributes && prevCell.attributes.colspan) {\n\t\t\t\t\t\tcolSpanCount += prevCell.attributes.colspan.value;\n\t\t\t\t} else {\n\t\t\t\t\tcolSpanCount -= 1;\n\t\t\t\t}\n\t\t\t\t$tw.utils.addAttributeToParseTreeNode(prevCell,\"colspan\",colSpanCount);\n\t\t\t}\n\t\t\tthis.parser.pos = cellRegExp.lastIndex - 1;\n\t\t\tbreak;\n\t\t} else {\n\t\t\t// For ordinary cells, step beyond the opening `|`\n\t\t\tthis.parser.pos++;\n\t\t\t// Look for a space at the start of the cell\n\t\t\tvar spaceLeft = false;\n\t\t\tvAlign = null;\n\t\t\tif(this.parser.source.substr(this.parser.pos).search(/^\\^([^\\^]|\\^\\^)/) === 0) {\n\t\t\t\tvAlign = \"top\";\n\t\t\t} else if(this.parser.source.substr(this.parser.pos).search(/^,([^,]|,,)/) === 0) {\n\t\t\t\tvAlign = \"bottom\";\n\t\t\t}\n\t\t\tif(vAlign) {\n\t\t\t\tthis.parser.pos++;\n\t\t\t}\n\t\t\tvar chr = this.parser.source.substr(this.parser.pos,1);\n\t\t\twhile(chr === \" \") {\n\t\t\t\tspaceLeft = true;\n\t\t\t\tthis.parser.pos++;\n\t\t\t\tchr = this.parser.source.substr(this.parser.pos,1);\n\t\t\t}\n\t\t\t// Check whether this is a heading cell\n\t\t\tvar cell;\n\t\t\tif(chr === \"!\") {\n\t\t\t\tthis.parser.pos++;\n\t\t\t\tcell = {type: \"element\", tag: \"th\", children: []};\n\t\t\t} else {\n\t\t\t\tcell = {type: \"element\", tag: \"td\", children: []};\n\t\t\t}\n\t\t\ttree.push(cell);\n\t\t\t// Record information about this cell\n\t\t\tprevCell = cell;\n\t\t\tprevColumns[col] = {rowSpanCount:1,element:cell};\n\t\t\t// Check for a colspan\n\t\t\tif(colSpanCount > 1) {\n\t\t\t\t$tw.utils.addAttributeToParseTreeNode(cell,\"colspan\",colSpanCount);\n\t\t\t\tcolSpanCount = 1;\n\t\t\t}\n\t\t\t// Parse the cell\n\t\t\tcell.children = this.parser.parseInlineRun(cellTermRegExp,{eatTerminator: true});\n\t\t\t// Set the alignment for the cell\n\t\t\tif(vAlign) {\n\t\t\t\t$tw.utils.addAttributeToParseTreeNode(cell,\"valign\",vAlign);\n\t\t\t}\n\t\t\tif(this.parser.source.substr(this.parser.pos - 2,1) === \" \") { // spaceRight\n\t\t\t\t$tw.utils.addAttributeToParseTreeNode(cell,\"align\",spaceLeft ? \"center\" : \"left\");\n\t\t\t} else if(spaceLeft) {\n\t\t\t\t$tw.utils.addAttributeToParseTreeNode(cell,\"align\",\"right\");\n\t\t\t}\n\t\t\t// Move back to the closing `|`\n\t\t\tthis.parser.pos--;\n\t\t}\n\t\tcol++;\n\t\tcellRegExp.lastIndex = this.parser.pos;\n\t\tcellMatch = cellRegExp.exec(this.parser.source);\n\t}\n\treturn tree;\n};\n\nexports.parse = function() {\n\tvar rowContainerTypes = {\"c\":\"caption\", \"h\":\"thead\", \"\":\"tbody\", \"f\":\"tfoot\"},\n\t\ttable = {type: \"element\", tag: \"table\", children: []},\n\t\trowRegExp = /^\\|([^\\n]*)\\|([fhck]?)\\r?(?:\\n|$)/mg,\n\t\trowTermRegExp = /(\\|(?:[fhck]?)\\r?(?:\\n|$))/mg,\n\t\tprevColumns = [],\n\t\tcurrRowType,\n\t\trowContainer,\n\t\trowCount = 0;\n\t// Match the row\n\trowRegExp.lastIndex = this.parser.pos;\n\tvar rowMatch = rowRegExp.exec(this.parser.source);\n\twhile(rowMatch && rowMatch.index === this.parser.pos) {\n\t\tvar rowType = rowMatch[2];\n\t\t// Check if it is a class assignment\n\t\tif(rowType === \"k\") {\n\t\t\t$tw.utils.addClassToParseTreeNode(table,rowMatch[1]);\n\t\t\tthis.parser.pos = rowMatch.index + rowMatch[0].length;\n\t\t} else {\n\t\t\t// Otherwise, create a new row if this one is of a different type\n\t\t\tif(rowType !== currRowType) {\n\t\t\t\trowContainer = {type: \"element\", tag: rowContainerTypes[rowType], children: []};\n\t\t\t\ttable.children.push(rowContainer);\n\t\t\t\tcurrRowType = rowType;\n\t\t\t}\n\t\t\t// Is this a caption row?\n\t\t\tif(currRowType === \"c\") {\n\t\t\t\t// If so, move past the opening `|` of the row\n\t\t\t\tthis.parser.pos++;\n\t\t\t\t// Move the caption to the first row if it isn't already\n\t\t\t\tif(table.children.length !== 1) {\n\t\t\t\t\ttable.children.pop(); // Take rowContainer out of the children array\n\t\t\t\t\ttable.children.splice(0,0,rowContainer); // Insert it at the bottom\t\t\t\t\t\t\n\t\t\t\t}\n\t\t\t\t// Set the alignment - TODO: figure out why TW did this\n//\t\t\t\trowContainer.attributes.align = rowCount === 0 ? \"top\" : \"bottom\";\n\t\t\t\t// Parse the caption\n\t\t\t\trowContainer.children = this.parser.parseInlineRun(rowTermRegExp,{eatTerminator: true});\n\t\t\t} else {\n\t\t\t\t// Create the row\n\t\t\t\tvar theRow = {type: \"element\", tag: \"tr\", children: []};\n\t\t\t\t$tw.utils.addClassToParseTreeNode(theRow,rowCount%2 ? \"oddRow\" : \"evenRow\");\n\t\t\t\trowContainer.children.push(theRow);\n\t\t\t\t// Process the row\n\t\t\t\ttheRow.children = processRow.call(this,prevColumns);\n\t\t\t\tthis.parser.pos = rowMatch.index + rowMatch[0].length;\n\t\t\t\t// Increment the row count\n\t\t\t\trowCount++;\n\t\t\t}\n\t\t}\n\t\trowMatch = rowRegExp.exec(this.parser.source);\n\t}\n\treturn [table];\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/transcludeblock.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/transcludeblock.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/transcludeblock.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text rule for block-level transclusion. For example:\n\n```\n{{MyTiddler}}\n{{MyTiddler||TemplateTitle}}\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"transcludeblock\";\nexports.types = {block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /\\{\\{([^\\{\\}\\|]*)(?:\\|\\|([^\\|\\{\\}]+))?\\}\\}(?:\\r?\\n|$)/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Get the match details\n\tvar template = $tw.utils.trim(this.match[2]),\n\t\ttextRef = $tw.utils.trim(this.match[1]);\n\t// Prepare the transclude widget\n\tvar transcludeNode = {\n\t\t\ttype: \"transclude\",\n\t\t\tattributes: {},\n\t\t\tisBlock: true\n\t\t};\n\t// Prepare the tiddler widget\n\tvar tr, targetTitle, targetField, targetIndex, tiddlerNode;\n\tif(textRef) {\n\t\ttr = $tw.utils.parseTextReference(textRef);\n\t\ttargetTitle = tr.title;\n\t\ttargetField = tr.field;\n\t\ttargetIndex = tr.index;\n\t\ttiddlerNode = {\n\t\t\ttype: \"tiddler\",\n\t\t\tattributes: {\n\t\t\t\ttiddler: {type: \"string\", value: targetTitle}\n\t\t\t},\n\t\t\tisBlock: true,\n\t\t\tchildren: [transcludeNode]\n\t\t};\n\t}\n\tif(template) {\n\t\ttranscludeNode.attributes.tiddler = {type: \"string\", value: template};\n\t\tif(textRef) {\n\t\t\treturn [tiddlerNode];\n\t\t} else {\n\t\t\treturn [transcludeNode];\n\t\t}\n\t} else {\n\t\tif(textRef) {\n\t\t\ttranscludeNode.attributes.tiddler = {type: \"string\", value: targetTitle};\n\t\t\tif(targetField) {\n\t\t\t\ttranscludeNode.attributes.field = {type: \"string\", value: targetField};\n\t\t\t}\n\t\t\tif(targetIndex) {\n\t\t\t\ttranscludeNode.attributes.index = {type: \"string\", value: targetIndex};\n\t\t\t}\n\t\t\treturn [tiddlerNode];\n\t\t} else {\n\t\t\treturn [transcludeNode];\n\t\t}\n\t}\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/transcludeinline.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/transcludeinline.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/transcludeinline.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text rule for inline-level transclusion. For example:\n\n```\n{{MyTiddler}}\n{{MyTiddler||TemplateTitle}}\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"transcludeinline\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /\\{\\{([^\\{\\}\\|]*)(?:\\|\\|([^\\|\\{\\}]+))?\\}\\}/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Get the match details\n\tvar template = $tw.utils.trim(this.match[2]),\n\t\ttextRef = $tw.utils.trim(this.match[1]);\n\t// Prepare the transclude widget\n\tvar transcludeNode = {\n\t\t\ttype: \"transclude\",\n\t\t\tattributes: {}\n\t\t};\n\t// Prepare the tiddler widget\n\tvar tr, targetTitle, targetField, targetIndex, tiddlerNode;\n\tif(textRef) {\n\t\ttr = $tw.utils.parseTextReference(textRef);\n\t\ttargetTitle = tr.title;\n\t\ttargetField = tr.field;\n\t\ttargetIndex = tr.index;\n\t\ttiddlerNode = {\n\t\t\ttype: \"tiddler\",\n\t\t\tattributes: {\n\t\t\t\ttiddler: {type: \"string\", value: targetTitle}\n\t\t\t},\n\t\t\tchildren: [transcludeNode]\n\t\t};\n\t}\n\tif(template) {\n\t\ttranscludeNode.attributes.tiddler = {type: \"string\", value: template};\n\t\tif(textRef) {\n\t\t\treturn [tiddlerNode];\n\t\t} else {\n\t\t\treturn [transcludeNode];\n\t\t}\n\t} else {\n\t\tif(textRef) {\n\t\t\ttranscludeNode.attributes.tiddler = {type: \"string\", value: targetTitle};\n\t\t\tif(targetField) {\n\t\t\t\ttranscludeNode.attributes.field = {type: \"string\", value: targetField};\n\t\t\t}\n\t\t\tif(targetIndex) {\n\t\t\t\ttranscludeNode.attributes.index = {type: \"string\", value: targetIndex};\n\t\t\t}\n\t\t\treturn [tiddlerNode];\n\t\t} else {\n\t\t\treturn [transcludeNode];\n\t\t}\n\t}\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/typedblock.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/typedblock.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/typedblock.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text rule for typed blocks. For example:\n\n```\n$$$.js\nThis will be rendered as JavaScript\n$$$\n\n$$$.svg\n<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"150\" height=\"100\">\n <circle cx=\"100\" cy=\"50\" r=\"40\" stroke=\"black\" stroke-width=\"2\" fill=\"red\" />\n</svg>\n$$$\n\n$$$text/vnd.tiddlywiki>text/html\nThis will be rendered as an //HTML representation// of WikiText\n$$$\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar widget = require(\"$:/core/modules/widgets/widget.js\");\n\nexports.name = \"typedblock\";\nexports.types = {block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /\\$\\$\\$([^ >\\r\\n]*)(?: *> *([^ \\r\\n]+))?\\r?\\n/mg;\n};\n\nexports.parse = function() {\n\tvar reEnd = /\\r?\\n\\$\\$\\$\\r?(?:\\n|$)/mg;\n\t// Save the type\n\tvar parseType = this.match[1],\n\t\trenderType = this.match[2];\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Look for the end of the block\n\treEnd.lastIndex = this.parser.pos;\n\tvar match = reEnd.exec(this.parser.source),\n\t\ttext;\n\t// Process the block\n\tif(match) {\n\t\ttext = this.parser.source.substring(this.parser.pos,match.index);\n\t\tthis.parser.pos = match.index + match[0].length;\n\t} else {\n\t\ttext = this.parser.source.substr(this.parser.pos);\n\t\tthis.parser.pos = this.parser.sourceLength;\n\t}\n\t// Parse the block according to the specified type\n\tvar parser = this.parser.wiki.parseText(parseType,text,{defaultType: \"text/plain\"});\n\t// If there's no render type, just return the parse tree\n\tif(!renderType) {\n\t\treturn parser.tree;\n\t} else {\n\t\t// Otherwise, render to the rendertype and return in a <PRE> tag\n\t\tvar widgetNode = this.parser.wiki.makeWidget(parser),\n\t\t\tcontainer = $tw.fakeDocument.createElement(\"div\");\n\t\twidgetNode.render(container,null);\n\t\ttext = renderType === \"text/html\" ? container.innerHTML : container.textContent;\n\t\treturn [{\n\t\t\ttype: \"element\",\n\t\t\ttag: \"pre\",\n\t\t\tchildren: [{\n\t\t\t\ttype: \"text\",\n\t\t\t\ttext: text\n\t\t\t}]\n\t\t}];\n\t}\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/whitespace.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/whitespace.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/whitespace.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki pragma rule for whitespace specifications\n\n```\n\\whitespace trim\n\\whitespace notrim\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"whitespace\";\nexports.types = {pragma: true};\n\n/*\nInstantiate parse rule\n*/\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /^\\\\whitespace[^\\S\\n]/mg;\n};\n\n/*\nParse the most recent match\n*/\nexports.parse = function() {\n\tvar self = this;\n\t// Move past the pragma invocation\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Parse whitespace delimited tokens terminated by a line break\n\tvar reMatch = /[^\\S\\n]*(\\S+)|(\\r?\\n)/mg,\n\t\ttokens = [];\n\treMatch.lastIndex = this.parser.pos;\n\tvar match = reMatch.exec(this.parser.source);\n\twhile(match && match.index === this.parser.pos) {\n\t\tthis.parser.pos = reMatch.lastIndex;\n\t\t// Exit if we've got the line break\n\t\tif(match[2]) {\n\t\t\tbreak;\n\t\t}\n\t\t// Process the token\n\t\tif(match[1]) {\n\t\t\ttokens.push(match[1]);\n\t\t}\n\t\t// Match the next token\n\t\tmatch = reMatch.exec(this.parser.source);\n\t}\n\t// Process the tokens\n\t$tw.utils.each(tokens,function(token) {\n\t\tswitch(token) {\n\t\t\tcase \"trim\":\n\t\t\t\tself.parser.configTrimWhiteSpace = true;\n\t\t\t\tbreak;\n\t\t\tcase \"notrim\":\n\t\t\t\tself.parser.configTrimWhiteSpace = false;\n\t\t\t\tbreak;\n\t\t}\n\t});\n\t// No parse tree nodes to return\n\treturn [];\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/rules/wikilink.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/wikilink.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/wikilink.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for wiki links. For example:\n\n```\nAWikiLink\nAnotherLink\n~SuppressedLink\n```\n\nPrecede a camel case word with `~` to prevent it from being recognised as a link.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"wikilink\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = new RegExp($tw.config.textPrimitives.unWikiLink + \"?\" + $tw.config.textPrimitives.wikiLink,\"mg\");\n};\n\n/*\nParse the most recent match\n*/\nexports.parse = function() {\n\t// Get the details of the match\n\tvar linkText = this.match[0];\n\t// Move past the macro call\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// If the link starts with the unwikilink character then just output it as plain text\n\tif(linkText.substr(0,1) === $tw.config.textPrimitives.unWikiLink) {\n\t\treturn [{type: \"text\", text: linkText.substr(1)}];\n\t}\n\t// If the link has been preceded with a blocked letter then don't treat it as a link\n\tif(this.match.index > 0) {\n\t\tvar preRegExp = new RegExp($tw.config.textPrimitives.blockPrefixLetters,\"mg\");\n\t\tpreRegExp.lastIndex = this.match.index-1;\n\t\tvar preMatch = preRegExp.exec(this.parser.source);\n\t\tif(preMatch && preMatch.index === this.match.index-1) {\n\t\t\treturn [{type: \"text\", text: linkText}];\n\t\t}\n\t}\n\treturn [{\n\t\ttype: \"link\",\n\t\tattributes: {\n\t\t\tto: {type: \"string\", value: linkText}\n\t\t},\n\t\tchildren: [{\n\t\t\ttype: \"text\",\n\t\t\ttext: linkText\n\t\t}]\n\t}];\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "wikirule"
},
"$:/core/modules/parsers/wikiparser/wikiparser.js": {
"title": "$:/core/modules/parsers/wikiparser/wikiparser.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/wikiparser.js\ntype: application/javascript\nmodule-type: parser\n\nThe wiki text parser processes blocks of source text into a parse tree.\n\nThe parse tree is made up of nested arrays of these JavaScript objects:\n\n\t{type: \"element\", tag: <string>, attributes: {}, children: []} - an HTML element\n\t{type: \"text\", text: <string>} - a text node\n\t{type: \"entity\", value: <string>} - an entity\n\t{type: \"raw\", html: <string>} - raw HTML\n\nAttributes are stored as hashmaps of the following objects:\n\n\t{type: \"string\", value: <string>} - literal string\n\t{type: \"indirect\", textReference: <textReference>} - indirect through a text reference\n\t{type: \"macro\", macro: <TBD>} - indirect through a macro invocation\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar WikiParser = function(type,text,options) {\n\tthis.wiki = options.wiki;\n\tvar self = this;\n\t// Check for an externally linked tiddler\n\tif($tw.browser && (text || \"\") === \"\" && options._canonical_uri) {\n\t\tthis.loadRemoteTiddler(options._canonical_uri);\n\t\ttext = $tw.language.getRawString(\"LazyLoadingWarning\");\n\t}\n\t// Initialise the classes if we don't have them already\n\tif(!this.pragmaRuleClasses) {\n\t\tWikiParser.prototype.pragmaRuleClasses = $tw.modules.createClassesFromModules(\"wikirule\",\"pragma\",$tw.WikiRuleBase);\n\t\tthis.setupRules(WikiParser.prototype.pragmaRuleClasses,\"$:/config/WikiParserRules/Pragmas/\");\n\t}\n\tif(!this.blockRuleClasses) {\n\t\tWikiParser.prototype.blockRuleClasses = $tw.modules.createClassesFromModules(\"wikirule\",\"block\",$tw.WikiRuleBase);\n\t\tthis.setupRules(WikiParser.prototype.blockRuleClasses,\"$:/config/WikiParserRules/Block/\");\n\t}\n\tif(!this.inlineRuleClasses) {\n\t\tWikiParser.prototype.inlineRuleClasses = $tw.modules.createClassesFromModules(\"wikirule\",\"inline\",$tw.WikiRuleBase);\n\t\tthis.setupRules(WikiParser.prototype.inlineRuleClasses,\"$:/config/WikiParserRules/Inline/\");\n\t}\n\t// Save the parse text\n\tthis.type = type || \"text/vnd.tiddlywiki\";\n\tthis.source = text || \"\";\n\tthis.sourceLength = this.source.length;\n\t// Flag for ignoring whitespace\n\tthis.configTrimWhiteSpace = false;\n\t// Set current parse position\n\tthis.pos = 0;\n\t// Instantiate the pragma parse rules\n\tthis.pragmaRules = this.instantiateRules(this.pragmaRuleClasses,\"pragma\",0);\n\t// Instantiate the parser block and inline rules\n\tthis.blockRules = this.instantiateRules(this.blockRuleClasses,\"block\",0);\n\tthis.inlineRules = this.instantiateRules(this.inlineRuleClasses,\"inline\",0);\n\t// Parse any pragmas\n\tthis.tree = [];\n\tvar topBranch = this.parsePragmas();\n\t// Parse the text into inline runs or blocks\n\tif(options.parseAsInline) {\n\t\ttopBranch.push.apply(topBranch,this.parseInlineRun());\n\t} else {\n\t\ttopBranch.push.apply(topBranch,this.parseBlocks());\n\t}\n\t// Return the parse tree\n};\n\n/*\n*/\nWikiParser.prototype.loadRemoteTiddler = function(url) {\n\tvar self = this;\n\t$tw.utils.httpRequest({\n\t\turl: url,\n\t\ttype: \"GET\",\n\t\tcallback: function(err,data) {\n\t\t\tif(!err) {\n\t\t\t\tvar tiddlers = self.wiki.deserializeTiddlers(\".tid\",data,self.wiki.getCreationFields());\n\t\t\t\t$tw.utils.each(tiddlers,function(tiddler) {\n\t\t\t\t\ttiddler[\"_canonical_uri\"] = url;\n\t\t\t\t});\n\t\t\t\tif(tiddlers) {\n\t\t\t\t\tself.wiki.addTiddlers(tiddlers);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n};\n\n/*\n*/\nWikiParser.prototype.setupRules = function(proto,configPrefix) {\n\tvar self = this;\n\tif(!$tw.safemode) {\n\t\t$tw.utils.each(proto,function(object,name) {\n\t\t\tif(self.wiki.getTiddlerText(configPrefix + name,\"enable\") !== \"enable\") {\n\t\t\t\tdelete proto[name];\n\t\t\t}\n\t\t});\n\t}\n};\n\n/*\nInstantiate an array of parse rules\n*/\nWikiParser.prototype.instantiateRules = function(classes,type,startPos) {\n\tvar rulesInfo = [],\n\t\tself = this;\n\t$tw.utils.each(classes,function(RuleClass) {\n\t\t// Instantiate the rule\n\t\tvar rule = new RuleClass(self);\n\t\trule.is = {};\n\t\trule.is[type] = true;\n\t\trule.init(self);\n\t\tvar matchIndex = rule.findNextMatch(startPos);\n\t\tif(matchIndex !== undefined) {\n\t\t\trulesInfo.push({\n\t\t\t\trule: rule,\n\t\t\t\tmatchIndex: matchIndex\n\t\t\t});\n\t\t}\n\t});\n\treturn rulesInfo;\n};\n\n/*\nSkip any whitespace at the current position. Options are:\n\ttreatNewlinesAsNonWhitespace: true if newlines are NOT to be treated as whitespace\n*/\nWikiParser.prototype.skipWhitespace = function(options) {\n\toptions = options || {};\n\tvar whitespaceRegExp = options.treatNewlinesAsNonWhitespace ? /([^\\S\\n]+)/mg : /(\\s+)/mg;\n\twhitespaceRegExp.lastIndex = this.pos;\n\tvar whitespaceMatch = whitespaceRegExp.exec(this.source);\n\tif(whitespaceMatch && whitespaceMatch.index === this.pos) {\n\t\tthis.pos = whitespaceRegExp.lastIndex;\n\t}\n};\n\n/*\nGet the next match out of an array of parse rule instances\n*/\nWikiParser.prototype.findNextMatch = function(rules,startPos) {\n\t// Find the best matching rule by finding the closest match position\n\tvar matchingRule,\n\t\tmatchingRulePos = this.sourceLength;\n\t// Step through each rule\n\tfor(var t=0; t<rules.length; t++) {\n\t\tvar ruleInfo = rules[t];\n\t\t// Ask the rule to get the next match if we've moved past the current one\n\t\tif(ruleInfo.matchIndex !== undefined && ruleInfo.matchIndex < startPos) {\n\t\t\truleInfo.matchIndex = ruleInfo.rule.findNextMatch(startPos);\n\t\t}\n\t\t// Adopt this match if it's closer than the current best match\n\t\tif(ruleInfo.matchIndex !== undefined && ruleInfo.matchIndex <= matchingRulePos) {\n\t\t\tmatchingRule = ruleInfo;\n\t\t\tmatchingRulePos = ruleInfo.matchIndex;\n\t\t}\n\t}\n\treturn matchingRule;\n};\n\n/*\nParse any pragmas at the beginning of a block of parse text\n*/\nWikiParser.prototype.parsePragmas = function() {\n\tvar currentTreeBranch = this.tree;\n\twhile(true) {\n\t\t// Skip whitespace\n\t\tthis.skipWhitespace();\n\t\t// Check for the end of the text\n\t\tif(this.pos >= this.sourceLength) {\n\t\t\tbreak;\n\t\t}\n\t\t// Check if we've arrived at a pragma rule match\n\t\tvar nextMatch = this.findNextMatch(this.pragmaRules,this.pos);\n\t\t// If not, just exit\n\t\tif(!nextMatch || nextMatch.matchIndex !== this.pos) {\n\t\t\tbreak;\n\t\t}\n\t\t// Process the pragma rule\n\t\tvar subTree = nextMatch.rule.parse();\n\t\tif(subTree.length > 0) {\n\t\t\t// Quick hack; we only cope with a single parse tree node being returned, which is true at the moment\n\t\t\tcurrentTreeBranch.push.apply(currentTreeBranch,subTree);\n\t\t\tsubTree[0].children = [];\n\t\t\tcurrentTreeBranch = subTree[0].children;\n\t\t}\n\t}\n\treturn currentTreeBranch;\n};\n\n/*\nParse a block from the current position\n\tterminatorRegExpString: optional regular expression string that identifies the end of plain paragraphs. Must not include capturing parenthesis\n*/\nWikiParser.prototype.parseBlock = function(terminatorRegExpString) {\n\tvar terminatorRegExp = terminatorRegExpString ? new RegExp(\"(\" + terminatorRegExpString + \"|\\\\r?\\\\n\\\\r?\\\\n)\",\"mg\") : /(\\r?\\n\\r?\\n)/mg;\n\tthis.skipWhitespace();\n\tif(this.pos >= this.sourceLength) {\n\t\treturn [];\n\t}\n\t// Look for a block rule that applies at the current position\n\tvar nextMatch = this.findNextMatch(this.blockRules,this.pos);\n\tif(nextMatch && nextMatch.matchIndex === this.pos) {\n\t\treturn nextMatch.rule.parse();\n\t}\n\t// Treat it as a paragraph if we didn't find a block rule\n\treturn [{type: \"element\", tag: \"p\", children: this.parseInlineRun(terminatorRegExp)}];\n};\n\n/*\nParse a series of blocks of text until a terminating regexp is encountered or the end of the text\n\tterminatorRegExpString: terminating regular expression\n*/\nWikiParser.prototype.parseBlocks = function(terminatorRegExpString) {\n\tif(terminatorRegExpString) {\n\t\treturn this.parseBlocksTerminated(terminatorRegExpString);\n\t} else {\n\t\treturn this.parseBlocksUnterminated();\n\t}\n};\n\n/*\nParse a block from the current position to the end of the text\n*/\nWikiParser.prototype.parseBlocksUnterminated = function() {\n\tvar tree = [];\n\twhile(this.pos < this.sourceLength) {\n\t\ttree.push.apply(tree,this.parseBlock());\n\t}\n\treturn tree;\n};\n\n/*\nParse blocks of text until a terminating regexp is encountered\n*/\nWikiParser.prototype.parseBlocksTerminated = function(terminatorRegExpString) {\n\tvar terminatorRegExp = new RegExp(\"(\" + terminatorRegExpString + \")\",\"mg\"),\n\t\ttree = [];\n\t// Skip any whitespace\n\tthis.skipWhitespace();\n\t// Check if we've got the end marker\n\tterminatorRegExp.lastIndex = this.pos;\n\tvar match = terminatorRegExp.exec(this.source);\n\t// Parse the text into blocks\n\twhile(this.pos < this.sourceLength && !(match && match.index === this.pos)) {\n\t\tvar blocks = this.parseBlock(terminatorRegExpString);\n\t\ttree.push.apply(tree,blocks);\n\t\t// Skip any whitespace\n\t\tthis.skipWhitespace();\n\t\t// Check if we've got the end marker\n\t\tterminatorRegExp.lastIndex = this.pos;\n\t\tmatch = terminatorRegExp.exec(this.source);\n\t}\n\tif(match && match.index === this.pos) {\n\t\tthis.pos = match.index + match[0].length;\n\t}\n\treturn tree;\n};\n\n/*\nParse a run of text at the current position\n\tterminatorRegExp: a regexp at which to stop the run\n\toptions: see below\nOptions available:\n\teatTerminator: move the parse position past any encountered terminator (default false)\n*/\nWikiParser.prototype.parseInlineRun = function(terminatorRegExp,options) {\n\tif(terminatorRegExp) {\n\t\treturn this.parseInlineRunTerminated(terminatorRegExp,options);\n\t} else {\n\t\treturn this.parseInlineRunUnterminated(options);\n\t}\n};\n\nWikiParser.prototype.parseInlineRunUnterminated = function(options) {\n\tvar tree = [];\n\t// Find the next occurrence of an inline rule\n\tvar nextMatch = this.findNextMatch(this.inlineRules,this.pos);\n\t// Loop around the matches until we've reached the end of the text\n\twhile(this.pos < this.sourceLength && nextMatch) {\n\t\t// Process the text preceding the run rule\n\t\tif(nextMatch.matchIndex > this.pos) {\n\t\t\tthis.pushTextWidget(tree,this.source.substring(this.pos,nextMatch.matchIndex));\n\t\t\tthis.pos = nextMatch.matchIndex;\n\t\t}\n\t\t// Process the run rule\n\t\ttree.push.apply(tree,nextMatch.rule.parse());\n\t\t// Look for the next run rule\n\t\tnextMatch = this.findNextMatch(this.inlineRules,this.pos);\n\t}\n\t// Process the remaining text\n\tif(this.pos < this.sourceLength) {\n\t\tthis.pushTextWidget(tree,this.source.substr(this.pos));\n\t}\n\tthis.pos = this.sourceLength;\n\treturn tree;\n};\n\nWikiParser.prototype.parseInlineRunTerminated = function(terminatorRegExp,options) {\n\toptions = options || {};\n\tvar tree = [];\n\t// Find the next occurrence of the terminator\n\tterminatorRegExp.lastIndex = this.pos;\n\tvar terminatorMatch = terminatorRegExp.exec(this.source);\n\t// Find the next occurrence of a inlinerule\n\tvar inlineRuleMatch = this.findNextMatch(this.inlineRules,this.pos);\n\t// Loop around until we've reached the end of the text\n\twhile(this.pos < this.sourceLength && (terminatorMatch || inlineRuleMatch)) {\n\t\t// Return if we've found the terminator, and it precedes any inline rule match\n\t\tif(terminatorMatch) {\n\t\t\tif(!inlineRuleMatch || inlineRuleMatch.matchIndex >= terminatorMatch.index) {\n\t\t\t\tif(terminatorMatch.index > this.pos) {\n\t\t\t\t\tthis.pushTextWidget(tree,this.source.substring(this.pos,terminatorMatch.index));\n\t\t\t\t}\n\t\t\t\tthis.pos = terminatorMatch.index;\n\t\t\t\tif(options.eatTerminator) {\n\t\t\t\t\tthis.pos += terminatorMatch[0].length;\n\t\t\t\t}\n\t\t\t\treturn tree;\n\t\t\t}\n\t\t}\n\t\t// Process any inline rule, along with the text preceding it\n\t\tif(inlineRuleMatch) {\n\t\t\t// Preceding text\n\t\t\tif(inlineRuleMatch.matchIndex > this.pos) {\n\t\t\t\tthis.pushTextWidget(tree,this.source.substring(this.pos,inlineRuleMatch.matchIndex));\n\t\t\t\tthis.pos = inlineRuleMatch.matchIndex;\n\t\t\t}\n\t\t\t// Process the inline rule\n\t\t\ttree.push.apply(tree,inlineRuleMatch.rule.parse());\n\t\t\t// Look for the next inline rule\n\t\t\tinlineRuleMatch = this.findNextMatch(this.inlineRules,this.pos);\n\t\t\t// Look for the next terminator match\n\t\t\tterminatorRegExp.lastIndex = this.pos;\n\t\t\tterminatorMatch = terminatorRegExp.exec(this.source);\n\t\t}\n\t}\n\t// Process the remaining text\n\tif(this.pos < this.sourceLength) {\n\t\tthis.pushTextWidget(tree,this.source.substr(this.pos));\n\t}\n\tthis.pos = this.sourceLength;\n\treturn tree;\n};\n\n/*\nPush a text widget onto an array, respecting the configTrimWhiteSpace setting\n*/\nWikiParser.prototype.pushTextWidget = function(array,text) {\n\tif(this.configTrimWhiteSpace) {\n\t\ttext = $tw.utils.trim(text);\n\t}\n\tif(text) {\n\t\tarray.push({type: \"text\", text: text});\t\t\n\t}\n};\n\n/*\nParse zero or more class specifiers `.classname`\n*/\nWikiParser.prototype.parseClasses = function() {\n\tvar classRegExp = /\\.([^\\s\\.]+)/mg,\n\t\tclassNames = [];\n\tclassRegExp.lastIndex = this.pos;\n\tvar match = classRegExp.exec(this.source);\n\twhile(match && match.index === this.pos) {\n\t\tthis.pos = match.index + match[0].length;\n\t\tclassNames.push(match[1]);\n\t\tmatch = classRegExp.exec(this.source);\n\t}\n\treturn classNames;\n};\n\n/*\nAmend the rules used by this instance of the parser\n\ttype: `only` keeps just the named rules, `except` keeps all but the named rules\n\tnames: array of rule names\n*/\nWikiParser.prototype.amendRules = function(type,names) {\n\tnames = names || [];\n\t// Define the filter function\n\tvar keepFilter;\n\tif(type === \"only\") {\n\t\tkeepFilter = function(name) {\n\t\t\treturn names.indexOf(name) !== -1;\n\t\t};\n\t} else if(type === \"except\") {\n\t\tkeepFilter = function(name) {\n\t\t\treturn names.indexOf(name) === -1;\n\t\t};\n\t} else {\n\t\treturn;\n\t}\n\t// Define a function to process each of our rule arrays\n\tvar processRuleArray = function(ruleArray) {\n\t\tfor(var t=ruleArray.length-1; t>=0; t--) {\n\t\t\tif(!keepFilter(ruleArray[t].rule.name)) {\n\t\t\t\truleArray.splice(t,1);\n\t\t\t}\n\t\t}\n\t};\n\t// Process each rule array\n\tprocessRuleArray(this.pragmaRules);\n\tprocessRuleArray(this.blockRules);\n\tprocessRuleArray(this.inlineRules);\n};\n\nexports[\"text/vnd.tiddlywiki\"] = WikiParser;\n\n})();\n\n",
"type": "application/javascript",
"module-type": "parser"
},
"$:/core/modules/parsers/wikiparser/rules/wikirulebase.js": {
"title": "$:/core/modules/parsers/wikiparser/rules/wikirulebase.js",
"text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/wikirulebase.js\ntype: application/javascript\nmodule-type: global\n\nBase class for wiki parser rules\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nThis constructor is always overridden with a blank constructor, and so shouldn't be used\n*/\nvar WikiRuleBase = function() {\n};\n\n/*\nTo be overridden by individual rules\n*/\nWikiRuleBase.prototype.init = function(parser) {\n\tthis.parser = parser;\n};\n\n/*\nDefault implementation of findNextMatch uses RegExp matching\n*/\nWikiRuleBase.prototype.findNextMatch = function(startPos) {\n\tthis.matchRegExp.lastIndex = startPos;\n\tthis.match = this.matchRegExp.exec(this.parser.source);\n\treturn this.match ? this.match.index : undefined;\n};\n\nexports.WikiRuleBase = WikiRuleBase;\n\n})();\n",
"type": "application/javascript",
"module-type": "global"
},
"$:/core/modules/pluginswitcher.js": {
"title": "$:/core/modules/pluginswitcher.js",
"text": "/*\\\ntitle: $:/core/modules/pluginswitcher.js\ntype: application/javascript\nmodule-type: global\n\nManages switching plugins for themes and languages.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\noptions:\nwiki: wiki store to be used\npluginType: type of plugin to be switched\ncontrollerTitle: title of tiddler used to control switching of this resource\ndefaultPlugins: array of default plugins to be used if nominated plugin isn't found\nonSwitch: callback when plugin is switched (single parameter is array of plugin titles)\n*/\nfunction PluginSwitcher(options) {\n\tthis.wiki = options.wiki;\n\tthis.pluginType = options.pluginType;\n\tthis.controllerTitle = options.controllerTitle;\n\tthis.defaultPlugins = options.defaultPlugins || [];\n\tthis.onSwitch = options.onSwitch;\n\t// Switch to the current plugin\n\tthis.switchPlugins();\n\t// Listen for changes to the selected plugin\n\tvar self = this;\n\tthis.wiki.addEventListener(\"change\",function(changes) {\n\t\tif($tw.utils.hop(changes,self.controllerTitle)) {\n\t\t\tself.switchPlugins();\n\t\t}\n\t});\n}\n\nPluginSwitcher.prototype.switchPlugins = function() {\n\t// Get the name of the current theme\n\tvar selectedPluginTitle = this.wiki.getTiddlerText(this.controllerTitle);\n\t// If it doesn't exist, then fallback to one of the default themes\n\tvar index = 0;\n\twhile(!this.wiki.getTiddler(selectedPluginTitle) && index < this.defaultPlugins.length) {\n\t\tselectedPluginTitle = this.defaultPlugins[index++];\n\t}\n\t// Accumulate the titles of the plugins that we need to load\n\tvar plugins = [],\n\t\tself = this,\n\t\taccumulatePlugin = function(title) {\n\t\t\tvar tiddler = self.wiki.getTiddler(title);\n\t\t\tif(tiddler && tiddler.isPlugin() && plugins.indexOf(title) === -1) {\n\t\t\t\tplugins.push(title);\n\t\t\t\tvar pluginInfo = JSON.parse(self.wiki.getTiddlerText(title)),\n\t\t\t\t\tdependents = $tw.utils.parseStringArray(tiddler.fields.dependents || \"\");\n\t\t\t\t$tw.utils.each(dependents,function(title) {\n\t\t\t\t\taccumulatePlugin(title);\n\t\t\t\t});\n\t\t\t}\n\t\t};\n\taccumulatePlugin(selectedPluginTitle);\n\t// Unregister any existing theme tiddlers\n\tvar unregisteredTiddlers = $tw.wiki.unregisterPluginTiddlers(this.pluginType);\n\t// Register any new theme tiddlers\n\tvar registeredTiddlers = $tw.wiki.registerPluginTiddlers(this.pluginType,plugins);\n\t// Unpack the current theme tiddlers\n\t$tw.wiki.unpackPluginTiddlers();\n\t// Call the switch handler\n\tif(this.onSwitch) {\n\t\tthis.onSwitch(plugins);\n\t}\n};\n\nexports.PluginSwitcher = PluginSwitcher;\n\n})();\n",
"type": "application/javascript",
"module-type": "global"
},
"$:/core/modules/saver-handler.js": {
"title": "$:/core/modules/saver-handler.js",
"text": "/*\\\ntitle: $:/core/modules/saver-handler.js\ntype: application/javascript\nmodule-type: global\n\nThe saver handler tracks changes to the store and handles saving the entire wiki via saver modules.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nInstantiate the saver handler with the following options:\nwiki: wiki to be synced\ndirtyTracking: true if dirty tracking should be performed\n*/\nfunction SaverHandler(options) {\n\tvar self = this;\n\tthis.wiki = options.wiki;\n\tthis.dirtyTracking = options.dirtyTracking;\n\tthis.pendingAutoSave = false;\n\t// Make a logger\n\tthis.logger = new $tw.utils.Logger(\"saver-handler\");\n\t// Initialise our savers\n\tif($tw.browser) {\n\t\tthis.initSavers();\n\t}\n\t// Only do dirty tracking if required\n\tif($tw.browser && this.dirtyTracking) {\n\t\t// Compile the dirty tiddler filter\n\t\tthis.filterFn = this.wiki.compileFilter(this.wiki.getTiddlerText(this.titleSyncFilter));\n\t\t// Count of changes that have not yet been saved\n\t\tthis.numChanges = 0;\n\t\t// Listen out for changes to tiddlers\n\t\tthis.wiki.addEventListener(\"change\",function(changes) {\n\t\t\t// Filter the changes so that we only count changes to tiddlers that we care about\n\t\t\tvar filteredChanges = self.filterFn.call(self.wiki,function(iterator) {\n\t\t\t\t$tw.utils.each(changes,function(change,title) {\n\t\t\t\t\tvar tiddler = self.wiki.getTiddler(title);\n\t\t\t\t\titerator(tiddler,title);\n\t\t\t\t});\n\t\t\t});\n\t\t\t// Adjust the number of changes\n\t\t\tself.numChanges += filteredChanges.length;\n\t\t\tself.updateDirtyStatus();\n\t\t\t// Do any autosave if one is pending and there's no more change events\n\t\t\tif(self.pendingAutoSave && self.wiki.getSizeOfTiddlerEventQueue() === 0) {\n\t\t\t\t// Check if we're dirty\n\t\t\t\tif(self.numChanges > 0) {\n\t\t\t\t\tself.saveWiki({\n\t\t\t\t\t\tmethod: \"autosave\",\n\t\t\t\t\t\tdownloadType: \"text/plain\"\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tself.pendingAutoSave = false;\n\t\t\t}\n\t\t});\n\t\t// Listen for the autosave event\n\t\t$tw.rootWidget.addEventListener(\"tm-auto-save-wiki\",function(event) {\n\t\t\t// Do the autosave unless there are outstanding tiddler change events\n\t\t\tif(self.wiki.getSizeOfTiddlerEventQueue() === 0) {\n\t\t\t\t// Check if we're dirty\n\t\t\t\tif(self.numChanges > 0) {\n\t\t\t\t\tself.saveWiki({\n\t\t\t\t\t\tmethod: \"autosave\",\n\t\t\t\t\t\tdownloadType: \"text/plain\"\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Otherwise put ourselves in the \"pending autosave\" state and wait for the change event before we do the autosave\n\t\t\t\tself.pendingAutoSave = true;\n\t\t\t}\n\t\t});\n\t\t// Set up our beforeunload handler\n\t\t$tw.addUnloadTask(function(event) {\n\t\t\tvar confirmationMessage;\n\t\t\tif(self.isDirty()) {\n\t\t\t\tconfirmationMessage = $tw.language.getString(\"UnsavedChangesWarning\");\n\t\t\t\tevent.returnValue = confirmationMessage; // Gecko\n\t\t\t}\n\t\t\treturn confirmationMessage;\n\t\t});\n\t}\n\t// Install the save action handlers\n\tif($tw.browser) {\n\t\t$tw.rootWidget.addEventListener(\"tm-save-wiki\",function(event) {\n\t\t\tself.saveWiki({\n\t\t\t\ttemplate: event.param,\n\t\t\t\tdownloadType: \"text/plain\",\n\t\t\t\tvariables: event.paramObject\n\t\t\t});\n\t\t});\n\t\t$tw.rootWidget.addEventListener(\"tm-download-file\",function(event) {\n\t\t\tself.saveWiki({\n\t\t\t\tmethod: \"download\",\n\t\t\t\ttemplate: event.param,\n\t\t\t\tdownloadType: \"text/plain\",\n\t\t\t\tvariables: event.paramObject\n\t\t\t});\n\t\t});\n\t}\n}\n\nSaverHandler.prototype.titleSyncFilter = \"$:/config/SaverFilter\";\nSaverHandler.prototype.titleAutoSave = \"$:/config/AutoSave\";\nSaverHandler.prototype.titleSavedNotification = \"$:/language/Notifications/Save/Done\";\n\n/*\nSelect the appropriate saver modules and set them up\n*/\nSaverHandler.prototype.initSavers = function(moduleType) {\n\tmoduleType = moduleType || \"saver\";\n\t// Instantiate the available savers\n\tthis.savers = [];\n\tvar self = this;\n\t$tw.modules.forEachModuleOfType(moduleType,function(title,module) {\n\t\tif(module.canSave(self)) {\n\t\t\tself.savers.push(module.create(self.wiki));\n\t\t}\n\t});\n\t// Sort the savers into priority order\n\tthis.savers.sort(function(a,b) {\n\t\tif(a.info.priority < b.info.priority) {\n\t\t\treturn -1;\n\t\t} else {\n\t\t\tif(a.info.priority > b.info.priority) {\n\t\t\t\treturn +1;\n\t\t\t} else {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t});\n};\n\n/*\nSave the wiki contents. Options are:\n\tmethod: \"save\", \"autosave\" or \"download\"\n\ttemplate: the tiddler containing the template to save\n\tdownloadType: the content type for the saved file\n*/\nSaverHandler.prototype.saveWiki = function(options) {\n\toptions = options || {};\n\tvar self = this,\n\t\tmethod = options.method || \"save\",\n\t\tvariables = options.variables || {},\n\t\ttemplate = options.template || \"$:/core/save/all\",\n\t\tdownloadType = options.downloadType || \"text/plain\",\n\t\ttext = this.wiki.renderTiddler(downloadType,template,options),\n\t\tcallback = function(err) {\n\t\t\tif(err) {\n\t\t\t\talert($tw.language.getString(\"Error/WhileSaving\") + \":\\n\\n\" + err);\n\t\t\t} else {\n\t\t\t\t// Clear the task queue if we're saving (rather than downloading)\n\t\t\t\tif(method !== \"download\") {\n\t\t\t\t\tself.numChanges = 0;\n\t\t\t\t\tself.updateDirtyStatus();\n\t\t\t\t}\n\t\t\t\t$tw.notifier.display(self.titleSavedNotification);\n\t\t\t\tif(options.callback) {\n\t\t\t\t\toptions.callback();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t// Ignore autosave if disabled\n\tif(method === \"autosave\" && this.wiki.getTiddlerText(this.titleAutoSave,\"yes\") !== \"yes\") {\n\t\treturn false;\n\t}\n\t// Call the highest priority saver that supports this method\n\tfor(var t=this.savers.length-1; t>=0; t--) {\n\t\tvar saver = this.savers[t];\n\t\tif(saver.info.capabilities.indexOf(method) !== -1 && saver.save(text,method,callback,{variables: {filename: variables.filename}})) {\n\t\t\tthis.logger.log(\"Saving wiki with method\",method,\"through saver\",saver.info.name);\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n};\n\n/*\nChecks whether the wiki is dirty (ie the window shouldn't be closed)\n*/\nSaverHandler.prototype.isDirty = function() {\n\treturn this.numChanges > 0;\n};\n\n/*\nUpdate the document body with the class \"tc-dirty\" if the wiki has unsaved/unsynced changes\n*/\nSaverHandler.prototype.updateDirtyStatus = function() {\n\tif($tw.browser) {\n\t\t$tw.utils.toggleClass(document.body,\"tc-dirty\",this.isDirty());\n\t}\n};\n\nexports.SaverHandler = SaverHandler;\n\n})();\n",
"type": "application/javascript",
"module-type": "global"
},
"$:/core/modules/savers/andtidwiki.js": {
"title": "$:/core/modules/savers/andtidwiki.js",
"text": "/*\\\ntitle: $:/core/modules/savers/andtidwiki.js\ntype: application/javascript\nmodule-type: saver\n\nHandles saving changes via the AndTidWiki Android app\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false, netscape: false, Components: false */\n\"use strict\";\n\nvar AndTidWiki = function(wiki) {\n};\n\nAndTidWiki.prototype.save = function(text,method,callback) {\n\t// Get the pathname of this document\n\tvar pathname = decodeURIComponent(document.location.toString().split(\"#\")[0]);\n\t// Strip the file://\n\tif(pathname.indexOf(\"file://\") === 0) {\n\t\tpathname = pathname.substr(7);\n\t}\n\t// Strip any query or location part\n\tvar p = pathname.indexOf(\"?\");\n\tif(p !== -1) {\n\t\tpathname = pathname.substr(0,p);\n\t}\n\tp = pathname.indexOf(\"#\");\n\tif(p !== -1) {\n\t\tpathname = pathname.substr(0,p);\n\t}\n\t// Save the file\n\twindow.twi.saveFile(pathname,text);\n\t// Call the callback\n\tcallback(null);\n\treturn true;\n};\n\n/*\nInformation about this saver\n*/\nAndTidWiki.prototype.info = {\n\tname: \"andtidwiki\",\n\tpriority: 1600,\n\tcapabilities: [\"save\", \"autosave\"]\n};\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\treturn !!window.twi && !!window.twi.saveFile;\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new AndTidWiki(wiki);\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "saver"
},
"$:/core/modules/savers/beaker.js": {
"title": "$:/core/modules/savers/beaker.js",
"text": "/*\\\ntitle: $:/core/modules/savers/beaker.js\ntype: application/javascript\nmodule-type: saver\n\nSaves files using the Beaker browser's (https://beakerbrowser.com) Dat protocol (https://datproject.org/)\nCompatible with beaker >= V0.7.2\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nSet up the saver\n*/\nvar BeakerSaver = function(wiki) {\n\tthis.wiki = wiki;\n};\n\nBeakerSaver.prototype.save = function(text,method,callback) {\n\tvar dat = new DatArchive(\"\" + window.location),\n\t\tpathname = (\"\" + window.location.pathname).split(\"#\")[0];\n\tdat.stat(pathname).then(function(value) {\n\t\tif(value.isDirectory()) {\n\t\t\tpathname = pathname + \"/index.html\";\n\t\t}\n\t\tdat.writeFile(pathname,text,\"utf8\").then(function(value) {\n\t\t\tcallback(null);\n\t\t},function(reason) {\n\t\t\tcallback(\"Beaker Saver Write Error: \" + reason);\n\t\t});\n\t},function(reason) {\n\t\tcallback(\"Beaker Saver Stat Error: \" + reason);\n\t});\n\treturn true;\n};\n\n/*\nInformation about this saver\n*/\nBeakerSaver.prototype.info = {\n\tname: \"beaker\",\n\tpriority: 3000,\n\tcapabilities: [\"save\", \"autosave\"]\n};\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\treturn !!window.DatArchive && location.protocol===\"dat:\";\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new BeakerSaver(wiki);\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "saver"
},
"$:/core/modules/savers/download.js": {
"title": "$:/core/modules/savers/download.js",
"text": "/*\\\ntitle: $:/core/modules/savers/download.js\ntype: application/javascript\nmodule-type: saver\n\nHandles saving changes via HTML5's download APIs\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nSelect the appropriate saver module and set it up\n*/\nvar DownloadSaver = function(wiki) {\n};\n\nDownloadSaver.prototype.save = function(text,method,callback,options) {\n\toptions = options || {};\n\t// Get the current filename\n\tvar filename = options.variables.filename;\n\tif(!filename) {\n\t\tvar p = document.location.pathname.lastIndexOf(\"/\");\n\t\tif(p !== -1) {\n\t\t\t// We decode the pathname because document.location is URL encoded by the browser\n\t\t\tfilename = decodeURIComponent(document.location.pathname.substr(p+1));\n\t\t}\n\t}\n\tif(!filename) {\n\t\tfilename = \"tiddlywiki.html\";\n\t}\n\t// Set up the link\n\tvar link = document.createElement(\"a\");\n\tif(Blob !== undefined) {\n\t\tvar blob = new Blob([text], {type: \"text/html\"});\n\t\tlink.setAttribute(\"href\", URL.createObjectURL(blob));\n\t} else {\n\t\tlink.setAttribute(\"href\",\"data:text/html,\" + encodeURIComponent(text));\n\t}\n\tlink.setAttribute(\"download\",filename);\n\tdocument.body.appendChild(link);\n\tlink.click();\n\tdocument.body.removeChild(link);\n\t// Callback that we succeeded\n\tcallback(null);\n\treturn true;\n};\n\n/*\nInformation about this saver\n*/\nDownloadSaver.prototype.info = {\n\tname: \"download\",\n\tpriority: 100\n};\n\nObject.defineProperty(DownloadSaver.prototype.info, \"capabilities\", {\n\tget: function() {\n\t\tvar capabilities = [\"save\", \"download\"];\n\t\tif(($tw.wiki.getTextReference(\"$:/config/DownloadSaver/AutoSave\") || \"\").toLowerCase() === \"yes\") {\n\t\t\tcapabilities.push(\"autosave\");\n\t\t}\n\t\treturn capabilities;\n\t}\n});\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\treturn document.createElement(\"a\").download !== undefined;\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new DownloadSaver(wiki);\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "saver"
},
"$:/core/modules/savers/fsosaver.js": {
"title": "$:/core/modules/savers/fsosaver.js",
"text": "/*\\\ntitle: $:/core/modules/savers/fsosaver.js\ntype: application/javascript\nmodule-type: saver\n\nHandles saving changes via MS FileSystemObject ActiveXObject\n\nNote: Since TiddlyWiki's markup contains the MOTW, the FileSystemObject normally won't be available. \nHowever, if the wiki is loaded as an .HTA file (Windows HTML Applications) then the FSO can be used.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nSelect the appropriate saver module and set it up\n*/\nvar FSOSaver = function(wiki) {\n};\n\nFSOSaver.prototype.save = function(text,method,callback) {\n\t// Get the pathname of this document\n\tvar pathname = unescape(document.location.pathname);\n\t// Test for a Windows path of the form /x:\\blah...\n\tif(/^\\/[A-Z]\\:\\\\[^\\\\]+/i.test(pathname)) {\t// ie: ^/[a-z]:/[^/]+\n\t\t// Remove the leading slash\n\t\tpathname = pathname.substr(1);\n\t} else if(document.location.hostname !== \"\" && /^\\/\\\\[^\\\\]+\\\\[^\\\\]+/i.test(pathname)) {\t// test for \\\\server\\share\\blah... - ^/[^/]+/[^/]+\n\t\t// Remove the leading slash\n\t\tpathname = pathname.substr(1);\n\t\t// reconstruct UNC path\n\t\tpathname = \"\\\\\\\\\" + document.location.hostname + pathname;\n\t} else {\n\t\treturn false;\n\t}\n\t// Save the file (as UTF-16)\n\tvar fso = new ActiveXObject(\"Scripting.FileSystemObject\");\n\tvar file = fso.OpenTextFile(pathname,2,-1,-1);\n\tfile.Write(text);\n\tfile.Close();\n\t// Callback that we succeeded\n\tcallback(null);\n\treturn true;\n};\n\n/*\nInformation about this saver\n*/\nFSOSaver.prototype.info = {\n\tname: \"FSOSaver\",\n\tpriority: 120,\n\tcapabilities: [\"save\", \"autosave\"]\n};\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\ttry {\n\t\treturn (window.location.protocol === \"file:\") && !!(new ActiveXObject(\"Scripting.FileSystemObject\"));\n\t} catch(e) { return false; }\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new FSOSaver(wiki);\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "saver"
},
"$:/core/modules/savers/manualdownload.js": {
"title": "$:/core/modules/savers/manualdownload.js",
"text": "/*\\\ntitle: $:/core/modules/savers/manualdownload.js\ntype: application/javascript\nmodule-type: saver\n\nHandles saving changes via HTML5's download APIs\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Title of the tiddler containing the download message\nvar downloadInstructionsTitle = \"$:/language/Modals/Download\";\n\n/*\nSelect the appropriate saver module and set it up\n*/\nvar ManualDownloadSaver = function(wiki) {\n};\n\nManualDownloadSaver.prototype.save = function(text,method,callback) {\n\t$tw.modal.display(downloadInstructionsTitle,{\n\t\tdownloadLink: \"data:text/html,\" + encodeURIComponent(text)\n\t});\n\t// Callback that we succeeded\n\tcallback(null);\n\treturn true;\n};\n\n/*\nInformation about this saver\n*/\nManualDownloadSaver.prototype.info = {\n\tname: \"manualdownload\",\n\tpriority: 0,\n\tcapabilities: [\"save\", \"download\"]\n};\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\treturn true;\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new ManualDownloadSaver(wiki);\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "saver"
},
"$:/core/modules/savers/msdownload.js": {
"title": "$:/core/modules/savers/msdownload.js",
"text": "/*\\\ntitle: $:/core/modules/savers/msdownload.js\ntype: application/javascript\nmodule-type: saver\n\nHandles saving changes via window.navigator.msSaveBlob()\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nSelect the appropriate saver module and set it up\n*/\nvar MsDownloadSaver = function(wiki) {\n};\n\nMsDownloadSaver.prototype.save = function(text,method,callback) {\n\t// Get the current filename\n\tvar filename = \"tiddlywiki.html\",\n\t\tp = document.location.pathname.lastIndexOf(\"/\");\n\tif(p !== -1) {\n\t\tfilename = document.location.pathname.substr(p+1);\n\t}\n\t// Set up the link\n\tvar blob = new Blob([text], {type: \"text/html\"});\n\twindow.navigator.msSaveBlob(blob,filename);\n\t// Callback that we succeeded\n\tcallback(null);\n\treturn true;\n};\n\n/*\nInformation about this saver\n*/\nMsDownloadSaver.prototype.info = {\n\tname: \"msdownload\",\n\tpriority: 110,\n\tcapabilities: [\"save\", \"download\"]\n};\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\treturn !!window.navigator.msSaveBlob;\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new MsDownloadSaver(wiki);\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "saver"
},
"$:/core/modules/savers/put.js": {
"title": "$:/core/modules/savers/put.js",
"text": "/*\\\ntitle: $:/core/modules/savers/put.js\ntype: application/javascript\nmodule-type: saver\n\nSaves wiki by performing a PUT request to the server\n\nWorks with any server which accepts a PUT request\nto the current URL, such as a WebDAV server.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nRetrieve ETag if available\n*/\nvar retrieveETag = function(self) {\n\tvar headers = {\n\t\tAccept: \"*/*;charset=UTF-8\"\n\t};\n\t$tw.utils.httpRequest({\n\t\turl: self.uri(),\n\t\ttype: \"HEAD\",\n\t\theaders: headers,\n\t\tcallback: function(err,data,xhr) {\n\t\t\tif(err) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tvar etag = xhr.getResponseHeader(\"ETag\");\n\t\t\tif(!etag) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tself.etag = etag.replace(/^W\\//,\"\");\n\t\t}\n\t});\n};\n\n\n/*\nSelect the appropriate saver module and set it up\n*/\nvar PutSaver = function(wiki) {\n\tthis.wiki = wiki;\n\tvar self = this;\n\tvar uri = this.uri();\n\t// Async server probe. Until probe finishes, save will fail fast\n\t// See also https://github.com/Jermolene/TiddlyWiki5/issues/2276\n\t$tw.utils.httpRequest({\n\t\turl: uri,\n\t\ttype: \"OPTIONS\",\n\t\tcallback: function(err,data,xhr) {\n\t\t\t// Check DAV header http://www.webdav.org/specs/rfc2518.html#rfc.section.9.1\n\t\t\tif(!err) {\n\t\t\t\tself.serverAcceptsPuts = xhr.status === 200 && !!xhr.getResponseHeader(\"dav\");\n\t\t\t}\n\t\t}\n\t});\n\tretrieveETag(this);\n};\n\nPutSaver.prototype.uri = function() {\n\treturn document.location.toString().split(\"#\")[0];\n};\n\n// TODO: in case of edit conflict\n// Prompt: Do you want to save over this? Y/N\n// Merging would be ideal, and may be possible using future generic merge flow\nPutSaver.prototype.save = function(text,method,callback) {\n\tif(!this.serverAcceptsPuts) {\n\t\treturn false;\n\t}\n\tvar self = this;\n\tvar headers = {\n\t\t\"Content-Type\": \"text/html;charset=UTF-8\"\n\t};\n\tif(this.etag) {\n\t\theaders[\"If-Match\"] = this.etag;\n\t}\n\t$tw.utils.httpRequest({\n\t\turl: this.uri(),\n\t\ttype: \"PUT\",\n\t\theaders: headers,\n\t\tdata: text,\n\t\tcallback: function(err,data,xhr) {\n\t\t\tif(err) {\n\t\t\t\t// response is textual: \"XMLHttpRequest error code: 412\"\n\t\t\t\tvar status = Number(err.substring(err.indexOf(':') + 2, err.length))\n\t\t\t\tif(status === 412) { // edit conflict\n\t\t\t\t\tvar message = $tw.language.getString(\"Error/EditConflict\");\n\t\t\t\t\tcallback(message);\n\t\t\t\t} else {\n\t\t\t\t\tcallback(err); // fail\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tself.etag = xhr.getResponseHeader(\"ETag\");\n\t\t\t\tif(self.etag == null) {\n\t\t\t\t\tretrieveETag(self);\n\t\t\t\t}\n\t\t\t\tcallback(null); // success\n\t\t\t}\n\t\t}\n\t});\n\treturn true;\n};\n\n/*\nInformation about this saver\n*/\nPutSaver.prototype.info = {\n\tname: \"put\",\n\tpriority: 2000,\n\tcapabilities: [\"save\",\"autosave\"]\n};\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\treturn /^https?:/.test(location.protocol);\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new PutSaver(wiki);\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "saver"
},
"$:/core/modules/savers/tiddlyfox.js": {
"title": "$:/core/modules/savers/tiddlyfox.js",
"text": "/*\\\ntitle: $:/core/modules/savers/tiddlyfox.js\ntype: application/javascript\nmodule-type: saver\n\nHandles saving changes via the TiddlyFox file extension\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false, netscape: false, Components: false */\n\"use strict\";\n\nvar TiddlyFoxSaver = function(wiki) {\n};\n\nTiddlyFoxSaver.prototype.save = function(text,method,callback) {\n\tvar messageBox = document.getElementById(\"tiddlyfox-message-box\");\n\tif(messageBox) {\n\t\t// Get the pathname of this document\n\t\tvar pathname = document.location.toString().split(\"#\")[0];\n\t\t// Replace file://localhost/ with file:///\n\t\tif(pathname.indexOf(\"file://localhost/\") === 0) {\n\t\t\tpathname = \"file://\" + pathname.substr(16);\n\t\t}\n\t\t// Windows path file:///x:/blah/blah --> x:\\blah\\blah\n\t\tif(/^file\\:\\/\\/\\/[A-Z]\\:\\//i.test(pathname)) {\n\t\t\t// Remove the leading slash and convert slashes to backslashes\n\t\t\tpathname = pathname.substr(8).replace(/\\//g,\"\\\\\");\n\t\t// Firefox Windows network path file://///server/share/blah/blah --> //server/share/blah/blah\n\t\t} else if(pathname.indexOf(\"file://///\") === 0) {\n\t\t\tpathname = \"\\\\\\\\\" + unescape(pathname.substr(10)).replace(/\\//g,\"\\\\\");\n\t\t// Mac/Unix local path file:///path/path --> /path/path\n\t\t} else if(pathname.indexOf(\"file:///\") === 0) {\n\t\t\tpathname = unescape(pathname.substr(7));\n\t\t// Mac/Unix local path file:/path/path --> /path/path\n\t\t} else if(pathname.indexOf(\"file:/\") === 0) {\n\t\t\tpathname = unescape(pathname.substr(5));\n\t\t// Otherwise Windows networth path file://server/share/path/path --> \\\\server\\share\\path\\path\n\t\t} else {\n\t\t\tpathname = \"\\\\\\\\\" + unescape(pathname.substr(7)).replace(new RegExp(\"/\",\"g\"),\"\\\\\");\n\t\t}\n\t\t// Create the message element and put it in the message box\n\t\tvar message = document.createElement(\"div\");\n\t\tmessage.setAttribute(\"data-tiddlyfox-path\",decodeURIComponent(pathname));\n\t\tmessage.setAttribute(\"data-tiddlyfox-content\",text);\n\t\tmessageBox.appendChild(message);\n\t\t// Add an event handler for when the file has been saved\n\t\tmessage.addEventListener(\"tiddlyfox-have-saved-file\",function(event) {\n\t\t\tcallback(null);\n\t\t}, false);\n\t\t// Create and dispatch the custom event to the extension\n\t\tvar event = document.createEvent(\"Events\");\n\t\tevent.initEvent(\"tiddlyfox-save-file\",true,false);\n\t\tmessage.dispatchEvent(event);\n\t\treturn true;\n\t} else {\n\t\treturn false;\n\t}\n};\n\n/*\nInformation about this saver\n*/\nTiddlyFoxSaver.prototype.info = {\n\tname: \"tiddlyfox\",\n\tpriority: 1500,\n\tcapabilities: [\"save\", \"autosave\"]\n};\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\treturn true;\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new TiddlyFoxSaver(wiki);\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "saver"
},
"$:/core/modules/savers/tiddlyie.js": {
"title": "$:/core/modules/savers/tiddlyie.js",
"text": "/*\\\ntitle: $:/core/modules/savers/tiddlyie.js\ntype: application/javascript\nmodule-type: saver\n\nHandles saving changes via Internet Explorer BHO extenion (TiddlyIE)\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nSelect the appropriate saver module and set it up\n*/\nvar TiddlyIESaver = function(wiki) {\n};\n\nTiddlyIESaver.prototype.save = function(text,method,callback) {\n\t// Check existence of TiddlyIE BHO extension (note: only works after document is complete)\n\tif(typeof(window.TiddlyIE) != \"undefined\") {\n\t\t// Get the pathname of this document\n\t\tvar pathname = unescape(document.location.pathname);\n\t\t// Test for a Windows path of the form /x:/blah...\n\t\tif(/^\\/[A-Z]\\:\\/[^\\/]+/i.test(pathname)) {\t// ie: ^/[a-z]:/[^/]+ (is this better?: ^/[a-z]:/[^/]+(/[^/]+)*\\.[^/]+ )\n\t\t\t// Remove the leading slash\n\t\t\tpathname = pathname.substr(1);\n\t\t\t// Convert slashes to backslashes\n\t\t\tpathname = pathname.replace(/\\//g,\"\\\\\");\n\t\t} else if(document.hostname !== \"\" && /^\\/[^\\/]+\\/[^\\/]+/i.test(pathname)) {\t// test for \\\\server\\share\\blah... - ^/[^/]+/[^/]+\n\t\t\t// Convert slashes to backslashes\n\t\t\tpathname = pathname.replace(/\\//g,\"\\\\\");\n\t\t\t// reconstruct UNC path\n\t\t\tpathname = \"\\\\\\\\\" + document.location.hostname + pathname;\n\t\t} else return false;\n\t\t// Prompt the user to save the file\n\t\twindow.TiddlyIE.save(pathname, text);\n\t\t// Callback that we succeeded\n\t\tcallback(null);\n\t\treturn true;\n\t} else {\n\t\treturn false;\n\t}\n};\n\n/*\nInformation about this saver\n*/\nTiddlyIESaver.prototype.info = {\n\tname: \"tiddlyiesaver\",\n\tpriority: 1500,\n\tcapabilities: [\"save\"]\n};\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\treturn (window.location.protocol === \"file:\");\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new TiddlyIESaver(wiki);\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "saver"
},
"$:/core/modules/savers/twedit.js": {
"title": "$:/core/modules/savers/twedit.js",
"text": "/*\\\ntitle: $:/core/modules/savers/twedit.js\ntype: application/javascript\nmodule-type: saver\n\nHandles saving changes via the TWEdit iOS app\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false, netscape: false, Components: false */\n\"use strict\";\n\nvar TWEditSaver = function(wiki) {\n};\n\nTWEditSaver.prototype.save = function(text,method,callback) {\n\t// Bail if we're not running under TWEdit\n\tif(typeof DeviceInfo !== \"object\") {\n\t\treturn false;\n\t}\n\t// Get the pathname of this document\n\tvar pathname = decodeURIComponent(document.location.pathname);\n\t// Strip any query or location part\n\tvar p = pathname.indexOf(\"?\");\n\tif(p !== -1) {\n\t\tpathname = pathname.substr(0,p);\n\t}\n\tp = pathname.indexOf(\"#\");\n\tif(p !== -1) {\n\t\tpathname = pathname.substr(0,p);\n\t}\n\t// Remove the leading \"/Documents\" from path\n\tvar prefix = \"/Documents\";\n\tif(pathname.indexOf(prefix) === 0) {\n\t\tpathname = pathname.substr(prefix.length);\n\t}\n\t// Error handler\n\tvar errorHandler = function(event) {\n\t\t// Error\n\t\tcallback($tw.language.getString(\"Error/SavingToTWEdit\") + \": \" + event.target.error.code);\n\t};\n\t// Get the file system\n\twindow.requestFileSystem(LocalFileSystem.PERSISTENT,0,function(fileSystem) {\n\t\t// Now we've got the filesystem, get the fileEntry\n\t\tfileSystem.root.getFile(pathname, {create: true}, function(fileEntry) {\n\t\t\t// Now we've got the fileEntry, create the writer\n\t\t\tfileEntry.createWriter(function(writer) {\n\t\t\t\twriter.onerror = errorHandler;\n\t\t\t\twriter.onwrite = function() {\n\t\t\t\t\tcallback(null);\n\t\t\t\t};\n\t\t\t\twriter.position = 0;\n\t\t\t\twriter.write(text);\n\t\t\t},errorHandler);\n\t\t}, errorHandler);\n\t}, errorHandler);\n\treturn true;\n};\n\n/*\nInformation about this saver\n*/\nTWEditSaver.prototype.info = {\n\tname: \"twedit\",\n\tpriority: 1600,\n\tcapabilities: [\"save\", \"autosave\"]\n};\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\treturn true;\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new TWEditSaver(wiki);\n};\n\n/////////////////////////// Hack\n// HACK: This ensures that TWEdit recognises us as a TiddlyWiki document\nif($tw.browser) {\n\twindow.version = {title: \"TiddlyWiki\"};\n}\n\n})();\n",
"type": "application/javascript",
"module-type": "saver"
},
"$:/core/modules/savers/upload.js": {
"title": "$:/core/modules/savers/upload.js",
"text": "/*\\\ntitle: $:/core/modules/savers/upload.js\ntype: application/javascript\nmodule-type: saver\n\nHandles saving changes via upload to a server.\n\nDesigned to be compatible with BidiX's UploadPlugin at http://tiddlywiki.bidix.info/#UploadPlugin\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nSelect the appropriate saver module and set it up\n*/\nvar UploadSaver = function(wiki) {\n\tthis.wiki = wiki;\n};\n\nUploadSaver.prototype.save = function(text,method,callback) {\n\t// Get the various parameters we need\n\tvar backupDir = this.wiki.getTextReference(\"$:/UploadBackupDir\") || \".\",\n\t\tusername = this.wiki.getTextReference(\"$:/UploadName\"),\n\t\tpassword = $tw.utils.getPassword(\"upload\"),\n\t\tuploadDir = this.wiki.getTextReference(\"$:/UploadDir\") || \".\",\n\t\tuploadFilename = this.wiki.getTextReference(\"$:/UploadFilename\") || \"index.html\",\n\t\turl = this.wiki.getTextReference(\"$:/UploadURL\");\n\t// Bail out if we don't have the bits we need\n\tif(!username || username.toString().trim() === \"\" || !password || password.toString().trim() === \"\") {\n\t\treturn false;\n\t}\n\t// Construct the url if not provided\n\tif(!url) {\n\t\turl = \"http://\" + username + \".tiddlyspot.com/store.cgi\";\n\t}\n\t// Assemble the header\n\tvar boundary = \"---------------------------\" + \"AaB03x\";\t\n\tvar uploadFormName = \"UploadPlugin\";\n\tvar head = [];\n\thead.push(\"--\" + boundary + \"\\r\\nContent-disposition: form-data; name=\\\"UploadPlugin\\\"\\r\\n\");\n\thead.push(\"backupDir=\" + backupDir + \";user=\" + username + \";password=\" + password + \";uploaddir=\" + uploadDir + \";;\"); \n\thead.push(\"\\r\\n\" + \"--\" + boundary);\n\thead.push(\"Content-disposition: form-data; name=\\\"userfile\\\"; filename=\\\"\" + uploadFilename + \"\\\"\");\n\thead.push(\"Content-Type: text/html;charset=UTF-8\");\n\thead.push(\"Content-Length: \" + text.length + \"\\r\\n\");\n\thead.push(\"\");\n\t// Assemble the tail and the data itself\n\tvar tail = \"\\r\\n--\" + boundary + \"--\\r\\n\",\n\t\tdata = head.join(\"\\r\\n\") + text + tail;\n\t// Do the HTTP post\n\tvar http = new XMLHttpRequest();\n\thttp.open(\"POST\",url,true,username,password);\n\thttp.setRequestHeader(\"Content-Type\",\"multipart/form-data; charset=UTF-8; boundary=\" + boundary);\n\thttp.onreadystatechange = function() {\n\t\tif(http.readyState == 4 && http.status == 200) {\n\t\t\tif(http.responseText.substr(0,4) === \"0 - \") {\n\t\t\t\tcallback(null);\n\t\t\t} else {\n\t\t\t\tcallback(http.responseText);\n\t\t\t}\n\t\t}\n\t};\n\ttry {\n\t\thttp.send(data);\n\t} catch(ex) {\n\t\treturn callback($tw.language.getString(\"Error/Caption\") + \":\" + ex);\n\t}\n\t$tw.notifier.display(\"$:/language/Notifications/Save/Starting\");\n\treturn true;\n};\n\n/*\nInformation about this saver\n*/\nUploadSaver.prototype.info = {\n\tname: \"upload\",\n\tpriority: 2000,\n\tcapabilities: [\"save\", \"autosave\"]\n};\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\treturn true;\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new UploadSaver(wiki);\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "saver"
},
"$:/core/modules/server/authenticators/basic.js": {
"title": "$:/core/modules/server/authenticators/basic.js",
"text": "/*\\\ntitle: $:/core/modules/server/authenticators/basic.js\ntype: application/javascript\nmodule-type: authenticator\n\nAuthenticator for WWW basic authentication\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nif($tw.node) {\n\tvar util = require(\"util\"),\n\t\tfs = require(\"fs\"),\n\t\turl = require(\"url\"),\n\t\tpath = require(\"path\");\n}\n\nfunction BasicAuthenticator(server) {\n\tthis.server = server;\n\tthis.credentialsData = [];\n}\n\n/*\nReturns true if the authenticator is active, false if it is inactive, or a string if there is an error\n*/\nBasicAuthenticator.prototype.init = function() {\n\t// Read the credentials data\n\tthis.credentialsFilepath = this.server.get(\"credentials\");\n\tif(this.credentialsFilepath) {\n\t\tvar resolveCredentialsFilepath = path.resolve($tw.boot.wikiPath,this.credentialsFilepath);\n\t\tif(fs.existsSync(resolveCredentialsFilepath) && !fs.statSync(resolveCredentialsFilepath).isDirectory()) {\n\t\t\tvar credentialsText = fs.readFileSync(resolveCredentialsFilepath,\"utf8\"),\n\t\t\t\tcredentialsData = $tw.utils.parseCsvStringWithHeader(credentialsText);\n\t\t\tif(typeof credentialsData === \"string\") {\n\t\t\t\treturn \"Error: \" + credentialsData + \" reading credentials from '\" + resolveCredentialsFilepath + \"'\";\n\t\t\t} else {\n\t\t\t\tthis.credentialsData = credentialsData;\n\t\t\t}\n\t\t} else {\n\t\t\treturn \"Error: Unable to load user credentials from '\" + credentialsFilepath + \"'\";\n\t\t}\n\t}\n\t// Add the hardcoded username and password if specified\n\tif(this.server.get(\"username\") && this.server.get(\"password\")) {\n\t\tthis.credentialsData = this.credentialsData || [];\n\t\tthis.credentialsData.push({\n\t\t\tusername: this.server.get(\"username\"),\n\t\t\tpassword: this.server.get(\"password\")\n\t\t});\n\t}\n\treturn this.credentialsData.length > 0;\n};\n\n/*\nReturns true if the request is authenticated and assigns the \"authenticatedUsername\" state variable.\nReturns false if the request couldn't be authenticated having sent an appropriate response to the browser\n*/\nBasicAuthenticator.prototype.authenticateRequest = function(request,response,state) {\n\t// Extract the incoming username and password from the request\n\tvar header = request.headers.authorization || \"\";\n\tif(!header && state.allowAnon) {\n\t\t// If there's no header and anonymous access is allowed then we don't set authenticatedUsername\n\t\treturn true;\n\t}\n\tvar token = header.split(/\\s+/).pop() || \"\",\n\t\tauth = $tw.utils.base64Decode(token),\n\t\tparts = auth.split(/:/),\n\t\tincomingUsername = parts[0],\n\t\tincomingPassword = parts[1];\n\t// Check that at least one of the credentials matches\n\tvar matchingCredentials = this.credentialsData.find(function(credential) {\n\t\treturn credential.username === incomingUsername && credential.password === incomingPassword;\n\t});\n\tif(matchingCredentials) {\n\t\t// If so, add the authenticated username to the request state\n\t\tstate.authenticatedUsername = incomingUsername;\n\t\treturn true;\n\t} else {\n\t\t// If not, return an authentication challenge\n\t\tresponse.writeHead(401,\"Authentication required\",{\n\t\t\t\"WWW-Authenticate\": 'Basic realm=\"Please provide your username and password to login to ' + state.server.servername + '\"'\n\t\t});\n\t\tresponse.end();\n\t\treturn false;\n\t}\n};\n\nexports.AuthenticatorClass = BasicAuthenticator;\n\n})();\n",
"type": "application/javascript",
"module-type": "authenticator"
},
"$:/core/modules/server/authenticators/header.js": {
"title": "$:/core/modules/server/authenticators/header.js",
"text": "/*\\\ntitle: $:/core/modules/server/authenticators/header.js\ntype: application/javascript\nmodule-type: authenticator\n\nAuthenticator for trusted header authentication\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nfunction HeaderAuthenticator(server) {\n\tthis.server = server;\n\tthis.header = server.get(\"authenticated-user-header\");\n}\n\n/*\nReturns true if the authenticator is active, false if it is inactive, or a string if there is an error\n*/\nHeaderAuthenticator.prototype.init = function() {\n\treturn !!this.header;\n};\n\n/*\nReturns true if the request is authenticated and assigns the \"authenticatedUsername\" state variable.\nReturns false if the request couldn't be authenticated having sent an appropriate response to the browser\n*/\nHeaderAuthenticator.prototype.authenticateRequest = function(request,response,state) {\n\t// Otherwise, authenticate as the username in the specified header\n\tvar username = request.headers[this.header];\n\tif(!username && !state.allowAnon) {\n\t\tresponse.writeHead(401,\"Authorization header required to login to '\" + state.server.servername + \"'\");\n\t\tresponse.end();\n\t\treturn false;\n\t} else {\n\t\t// authenticatedUsername will be undefined for anonymous users\n\t\tstate.authenticatedUsername = username;\n\t\treturn true;\n\t}\n};\n\nexports.AuthenticatorClass = HeaderAuthenticator;\n\n})();\n",
"type": "application/javascript",
"module-type": "authenticator"
},
"$:/core/modules/server/routes/delete-tiddler.js": {
"title": "$:/core/modules/server/routes/delete-tiddler.js",
"text": "/*\\\ntitle: $:/core/modules/server/routes/delete-tiddler.js\ntype: application/javascript\nmodule-type: route\n\nDELETE /recipes/default/tiddlers/:title\n\n\\*/\n(function() {\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.method = \"DELETE\";\n\nexports.path = /^\\/bags\\/default\\/tiddlers\\/(.+)$/;\n\nexports.handler = function(request,response,state) {\n\tvar title = decodeURIComponent(state.params[0]);\n\tstate.wiki.deleteTiddler(title);\n\tresponse.writeHead(204, \"OK\", {\n\t\t\"Content-Type\": \"text/plain\"\n\t});\n\tresponse.end();\n};\n\n}());\n",
"type": "application/javascript",
"module-type": "route"
},
"$:/core/modules/server/routes/get-favicon.js": {
"title": "$:/core/modules/server/routes/get-favicon.js",
"text": "/*\\\ntitle: $:/core/modules/server/routes/get-favicon.js\ntype: application/javascript\nmodule-type: route\n\nGET /favicon.ico\n\n\\*/\n(function() {\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.method = \"GET\";\n\nexports.path = /^\\/favicon.ico$/;\n\nexports.handler = function(request,response,state) {\n\tresponse.writeHead(200, {\"Content-Type\": \"image/x-icon\"});\n\tvar buffer = state.wiki.getTiddlerText(\"$:/favicon.ico\",\"\");\n\tresponse.end(buffer,\"base64\");\n};\n\n}());\n",
"type": "application/javascript",
"module-type": "route"
},
"$:/core/modules/server/routes/get-file.js": {
"title": "$:/core/modules/server/routes/get-file.js",
"text": "/*\\\ntitle: $:/core/modules/server/routes/get-file.js\ntype: application/javascript\nmodule-type: route\n\nGET /files/:filepath\n\n\\*/\n(function() {\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.method = \"GET\";\n\nexports.path = /^\\/files\\/(.+)$/;\n\nexports.handler = function(request,response,state) {\n\tvar path = require(\"path\"),\n\t\tfs = require(\"fs\"),\n\t\tutil = require(\"util\");\n\tvar filename = path.resolve($tw.boot.wikiPath,\"files\",decodeURIComponent(state.params[0])),\n\t\textension = path.extname(filename);\n\tfs.readFile(filename,function(err,content) {\n\t\tvar status,content,type = \"text/plain\";\n\t\tif(err) {\n\t\t\tif(err.code === \"ENOENT\") {\n\t\t\t\tstatus = 404;\n\t\t\t\tcontent = \"File '\" + filename + \"' not found\";\n\t\t\t} else if(err.code === \"EACCES\") {\n\t\t\t\tstatus = 403;\n\t\t\t\tcontent = \"You do not have permission to access the file '\" + filename + \"'\";\n\t\t\t} else {\n\t\t\t\tstatus = 500;\n\t\t\t\tcontent = err.toString();\n\t\t\t}\n\t\t} else {\n\t\t\tstatus = 200;\n\t\t\tcontent = content;\n\t\t\ttype = ($tw.config.fileExtensionInfo[extension] ? $tw.config.fileExtensionInfo[extension].type : \"application/octet-stream\");\n\t\t}\n\t\tresponse.writeHead(status,{\n\t\t\t\"Content-Type\": type\n\t\t});\n\t\tresponse.end(content);\n\t});\n};\n\n}());\n",
"type": "application/javascript",
"module-type": "route"
},
"$:/core/modules/server/routes/get-index.js": {
"title": "$:/core/modules/server/routes/get-index.js",
"text": "/*\\\ntitle: $:/core/modules/server/routes/get-index.js\ntype: application/javascript\nmodule-type: route\n\nGET /\n\n\\*/\n(function() {\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.method = \"GET\";\n\nexports.path = /^\\/$/;\n\nexports.handler = function(request,response,state) {\n\tresponse.writeHead(200, {\"Content-Type\": state.server.get(\"root-serve-type\")});\n\tvar text = state.wiki.renderTiddler(state.server.get(\"root-render-type\"),state.server.get(\"root-tiddler\"));\n\tresponse.end(text,\"utf8\");\n};\n\n}());\n",
"type": "application/javascript",
"module-type": "route"
},
"$:/core/modules/server/routes/get-login-basic.js": {
"title": "$:/core/modules/server/routes/get-login-basic.js",
"text": "/*\\\ntitle: $:/core/modules/server/routes/get-login-basic.js\ntype: application/javascript\nmodule-type: route\n\nGET /login-basic -- force a Basic Authentication challenge\n\n\\*/\n(function() {\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.method = \"GET\";\n\nexports.path = /^\\/login-basic$/;\n\nexports.handler = function(request,response,state) {\n\tif(!state.authenticatedUsername) {\n\t\t// Challenge if there's no username\n\t\tresponse.writeHead(401,{\n\t\t\t\"WWW-Authenticate\": 'Basic realm=\"Please provide your username and password to login to ' + state.server.servername + '\"'\n\t\t});\n\t\tresponse.end();\t\t\n\t} else {\n\t\t// Redirect to the root wiki if login worked\n\t\tresponse.writeHead(302,{\n\t\t\tLocation: \"/\"\n\t\t});\n\t\tresponse.end();\n\t}\n};\n\n}());\n",
"type": "application/javascript",
"module-type": "route"
},
"$:/core/modules/server/routes/get-status.js": {
"title": "$:/core/modules/server/routes/get-status.js",
"text": "/*\\\ntitle: $:/core/modules/server/routes/get-status.js\ntype: application/javascript\nmodule-type: route\n\nGET /status\n\n\\*/\n(function() {\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.method = \"GET\";\n\nexports.path = /^\\/status$/;\n\nexports.handler = function(request,response,state) {\n\tresponse.writeHead(200, {\"Content-Type\": \"application/json\"});\n\tvar text = JSON.stringify({\n\t\tusername: state.authenticatedUsername || state.server.get(\"anon-username\") || \"\",\n\t\tanonymous: !state.authenticatedUsername,\n\t\tread_only: !state.server.isAuthorized(\"writers\",state.authenticatedUsername),\n\t\tspace: {\n\t\t\trecipe: \"default\"\n\t\t},\n\t\ttiddlywiki_version: $tw.version\n\t});\n\tresponse.end(text,\"utf8\");\n};\n\n}());\n",
"type": "application/javascript",
"module-type": "route"
},
"$:/core/modules/server/routes/get-tiddler-html.js": {
"title": "$:/core/modules/server/routes/get-tiddler-html.js",
"text": "/*\\\ntitle: $:/core/modules/server/routes/get-tiddler-html.js\ntype: application/javascript\nmodule-type: route\n\nGET /:title\n\n\\*/\n(function() {\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.method = \"GET\";\n\nexports.path = /^\\/([^\\/]+)$/;\n\nexports.handler = function(request,response,state) {\n\tvar title = decodeURIComponent(state.params[0]),\n\t\ttiddler = state.wiki.getTiddler(title);\n\tif(tiddler) {\n\t\tvar renderType = tiddler.getFieldString(\"_render_type\"),\n\t\t\trenderTemplate = tiddler.getFieldString(\"_render_template\");\n\t\t// Tiddler fields '_render_type' and '_render_template' overwrite\n\t\t// system wide settings for render type and template\n\t\tif(state.wiki.isSystemTiddler(title)) {\n\t\t\trenderType = renderType || state.server.get(\"system-tiddler-render-type\");\n\t\t\trenderTemplate = renderTemplate || state.server.get(\"system-tiddler-render-template\");\n\t\t} else {\n\t\t\trenderType = renderType || state.server.get(\"tiddler-render-type\");\n\t\t\trenderTemplate = renderTemplate || state.server.get(\"tiddler-render-template\");\n\t\t}\n\t\tvar text = state.wiki.renderTiddler(renderType,renderTemplate,{parseAsInline: true, variables: {currentTiddler: title}});\n\t\t// Naughty not to set a content-type, but it's the easiest way to ensure the browser will see HTML pages as HTML, and accept plain text tiddlers as CSS or JS\n\t\tresponse.writeHead(200);\n\t\tresponse.end(text,\"utf8\");\n\t} else {\n\t\tresponse.writeHead(404);\n\t\tresponse.end();\n\t}\n};\n\n}());\n",
"type": "application/javascript",
"module-type": "route"
},
"$:/core/modules/server/routes/get-tiddler.js": {
"title": "$:/core/modules/server/routes/get-tiddler.js",
"text": "/*\\\ntitle: $:/core/modules/server/routes/get-tiddler.js\ntype: application/javascript\nmodule-type: route\n\nGET /recipes/default/tiddlers/:title\n\n\\*/\n(function() {\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.method = \"GET\";\n\nexports.path = /^\\/recipes\\/default\\/tiddlers\\/(.+)$/;\n\nexports.handler = function(request,response,state) {\n\tvar title = decodeURIComponent(state.params[0]),\n\t\ttiddler = state.wiki.getTiddler(title),\n\t\ttiddlerFields = {},\n\t\tknownFields = [\n\t\t\t\"bag\", \"created\", \"creator\", \"modified\", \"modifier\", \"permissions\", \"recipe\", \"revision\", \"tags\", \"text\", \"title\", \"type\", \"uri\"\n\t\t];\n\tif(tiddler) {\n\t\t$tw.utils.each(tiddler.fields,function(field,name) {\n\t\t\tvar value = tiddler.getFieldString(name);\n\t\t\tif(knownFields.indexOf(name) !== -1) {\n\t\t\t\ttiddlerFields[name] = value;\n\t\t\t} else {\n\t\t\t\ttiddlerFields.fields = tiddlerFields.fields || {};\n\t\t\t\ttiddlerFields.fields[name] = value;\n\t\t\t}\n\t\t});\n\t\ttiddlerFields.revision = state.wiki.getChangeCount(title);\n\t\ttiddlerFields.type = tiddlerFields.type || \"text/vnd.tiddlywiki\";\n\t\tresponse.writeHead(200, {\"Content-Type\": \"application/json\"});\n\t\tresponse.end(JSON.stringify(tiddlerFields),\"utf8\");\n\t} else {\n\t\tresponse.writeHead(404);\n\t\tresponse.end();\n\t}\n};\n\n}());\n",
"type": "application/javascript",
"module-type": "route"
},
"$:/core/modules/server/routes/get-tiddlers-json.js": {
"title": "$:/core/modules/server/routes/get-tiddlers-json.js",
"text": "/*\\\ntitle: $:/core/modules/server/routes/get-tiddlers-json.js\ntype: application/javascript\nmodule-type: route\n\nGET /recipes/default/tiddlers/tiddlers.json\n\n\\*/\n(function() {\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.method = \"GET\";\n\nexports.path = /^\\/recipes\\/default\\/tiddlers.json$/;\n\nexports.handler = function(request,response,state) {\n\tresponse.writeHead(200, {\"Content-Type\": \"application/json\"});\n\tvar tiddlers = [];\n\tstate.wiki.forEachTiddler({sortField: \"title\"},function(title,tiddler) {\n\t\tvar tiddlerFields = {};\n\t\t$tw.utils.each(tiddler.fields,function(field,name) {\n\t\t\tif(name !== \"text\") {\n\t\t\t\ttiddlerFields[name] = tiddler.getFieldString(name);\n\t\t\t}\n\t\t});\n\t\ttiddlerFields.revision = state.wiki.getChangeCount(title);\n\t\ttiddlerFields.type = tiddlerFields.type || \"text/vnd.tiddlywiki\";\n\t\ttiddlers.push(tiddlerFields);\n\t});\n\tvar text = JSON.stringify(tiddlers);\n\tresponse.end(text,\"utf8\");\n};\n\n}());\n",
"type": "application/javascript",
"module-type": "route"
},
"$:/core/modules/server/routes/put-tiddler.js": {
"title": "$:/core/modules/server/routes/put-tiddler.js",
"text": "/*\\\ntitle: $:/core/modules/server/routes/put-tiddler.js\ntype: application/javascript\nmodule-type: route\n\nPUT /recipes/default/tiddlers/:title\n\n\\*/\n(function() {\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.method = \"PUT\";\n\nexports.path = /^\\/recipes\\/default\\/tiddlers\\/(.+)$/;\n\nexports.handler = function(request,response,state) {\n\tvar title = decodeURIComponent(state.params[0]),\n\tfields = JSON.parse(state.data);\n\t// Pull up any subfields in the `fields` object\n\tif(fields.fields) {\n\t\t$tw.utils.each(fields.fields,function(field,name) {\n\t\t\tfields[name] = field;\n\t\t});\n\t\tdelete fields.fields;\n\t}\n\t// Remove any revision field\n\tif(fields.revision) {\n\t\tdelete fields.revision;\n\t}\n\tstate.wiki.addTiddler(new $tw.Tiddler(state.wiki.getCreationFields(),fields,{title: title},state.wiki.getModificationFields()));\n\tvar changeCount = state.wiki.getChangeCount(title).toString();\n\tresponse.writeHead(204, \"OK\",{\n\t\tEtag: \"\\\"default/\" + encodeURIComponent(title) + \"/\" + changeCount + \":\\\"\",\n\t\t\"Content-Type\": \"text/plain\"\n\t});\n\tresponse.end();\n};\n\n}());\n",
"type": "application/javascript",
"module-type": "route"
},
"$:/core/modules/server/server.js": {
"title": "$:/core/modules/server/server.js",
"text": "/*\\\ntitle: $:/core/modules/server/server.js\ntype: application/javascript\nmodule-type: library\n\nServe tiddlers over http\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nif($tw.node) {\n\tvar util = require(\"util\"),\n\t\tfs = require(\"fs\"),\n\t\turl = require(\"url\"),\n\t\tpath = require(\"path\");\n}\n\n/*\nA simple HTTP server with regexp-based routes\noptions: variables - optional hashmap of variables to set (a misnomer - they are really constant parameters)\n\t\t routes - optional array of routes to use\n\t\t wiki - reference to wiki object\n*/\nfunction Server(options) {\n\tvar self = this;\n\tthis.routes = options.routes || [];\n\tthis.authenticators = options.authenticators || [];\n\tthis.wiki = options.wiki;\n\tthis.servername = $tw.utils.transliterateToSafeASCII(this.wiki.getTiddlerText(\"$:/SiteTitle\") || \"TiddlyWiki5\");\n\t// Initialise the variables\n\tthis.variables = $tw.utils.extend({},this.defaultVariables);\n\tif(options.variables) {\n\t\tfor(var variable in options.variables) {\n\t\t\tif(options.variables[variable]) {\n\t\t\t\tthis.variables[variable] = options.variables[variable];\n\t\t\t}\n\t\t}\t\t\n\t}\n\t$tw.utils.extend({},this.defaultVariables,options.variables);\n\t// Initialise CSRF\n\tthis.csrfDisable = this.get(\"csrf-disable\") === \"yes\";\n\t// Initialise authorization\n\tvar authorizedUserName = (this.get(\"username\") && this.get(\"password\")) ? this.get(\"username\") : \"(anon)\";\n\tthis.authorizationPrincipals = {\n\t\treaders: (this.get(\"readers\") || authorizedUserName).split(\",\").map($tw.utils.trim),\n\t\twriters: (this.get(\"writers\") || authorizedUserName).split(\",\").map($tw.utils.trim)\n\t}\n\t// Load and initialise authenticators\n\t$tw.modules.forEachModuleOfType(\"authenticator\", function(title,authenticatorDefinition) {\n\t\t// console.log(\"Loading server route \" + title);\n\t\tself.addAuthenticator(authenticatorDefinition.AuthenticatorClass);\n\t});\n\t// Load route handlers\n\t$tw.modules.forEachModuleOfType(\"route\", function(title,routeDefinition) {\n\t\t// console.log(\"Loading server route \" + title);\n\t\tself.addRoute(routeDefinition);\n\t});\n\t// Initialise the http vs https\n\tthis.listenOptions = null;\n\tthis.protocol = \"http\";\n\tvar tlsKeyFilepath = this.get(\"tls-key\"),\n\t\ttlsCertFilepath = this.get(\"tls-cert\");\n\tif(tlsCertFilepath && tlsKeyFilepath) {\n\t\tthis.listenOptions = {\n\t\t\tkey: fs.readFileSync(path.resolve($tw.boot.wikiPath,tlsKeyFilepath),\"utf8\"),\n\t\t\tcert: fs.readFileSync(path.resolve($tw.boot.wikiPath,tlsCertFilepath),\"utf8\")\n\t\t};\n\t\tthis.protocol = \"https\";\n\t}\n\tthis.transport = require(this.protocol);\n}\n\nServer.prototype.defaultVariables = {\n\tport: \"8080\",\n\thost: \"127.0.0.1\",\n\t\"root-tiddler\": \"$:/core/save/all\",\n\t\"root-render-type\": \"text/plain\",\n\t\"root-serve-type\": \"text/html\",\n\t\"tiddler-render-type\": \"text/html\",\n\t\"tiddler-render-template\": \"$:/core/templates/server/static.tiddler.html\",\n\t\"system-tiddler-render-type\": \"text/plain\",\n\t\"system-tiddler-render-template\": \"$:/core/templates/wikified-tiddler\",\n\t\"debug-level\": \"none\"\n};\n\nServer.prototype.get = function(name) {\n\treturn this.variables[name];\n};\n\nServer.prototype.addRoute = function(route) {\n\tthis.routes.push(route);\n};\n\nServer.prototype.addAuthenticator = function(AuthenticatorClass) {\n\t// Instantiate and initialise the authenticator\n\tvar authenticator = new AuthenticatorClass(this),\n\t\tresult = authenticator.init();\n\tif(typeof result === \"string\") {\n\t\t$tw.utils.error(\"Error: \" + result);\n\t} else if(result) {\n\t\t// Only use the authenticator if it initialised successfully\n\t\tthis.authenticators.push(authenticator);\n\t}\n};\n\nServer.prototype.findMatchingRoute = function(request,state) {\n\tvar pathprefix = this.get(\"path-prefix\") || \"\";\n\tfor(var t=0; t<this.routes.length; t++) {\n\t\tvar potentialRoute = this.routes[t],\n\t\t\tpathRegExp = potentialRoute.path,\n\t\t\tpathname = state.urlInfo.pathname,\n\t\t\tmatch;\n\t\tif(pathprefix) {\n\t\t\tif(pathname.substr(0,pathprefix.length) === pathprefix) {\n\t\t\t\tpathname = pathname.substr(pathprefix.length) || \"/\";\n\t\t\t\tmatch = potentialRoute.path.exec(pathname);\n\t\t\t} else {\n\t\t\t\tmatch = false;\n\t\t\t}\n\t\t} else {\n\t\t\tmatch = potentialRoute.path.exec(pathname);\n\t\t}\n\t\tif(match && request.method === potentialRoute.method) {\n\t\t\tstate.params = [];\n\t\t\tfor(var p=1; p<match.length; p++) {\n\t\t\t\tstate.params.push(match[p]);\n\t\t\t}\n\t\t\treturn potentialRoute;\n\t\t}\n\t}\n\treturn null;\n};\n\nServer.prototype.methodMappings = {\n\t\"GET\": \"readers\",\n\t\"OPTIONS\": \"readers\",\n\t\"HEAD\": \"readers\",\n\t\"PUT\": \"writers\",\n\t\"POST\": \"writers\",\n\t\"DELETE\": \"writers\"\n};\n\n/*\nCheck whether a given user is authorized for the specified authorizationType (\"readers\" or \"writers\"). Pass null or undefined as the username to check for anonymous access\n*/\nServer.prototype.isAuthorized = function(authorizationType,username) {\n\tvar principals = this.authorizationPrincipals[authorizationType] || [];\n\treturn principals.indexOf(\"(anon)\") !== -1 || (username && (principals.indexOf(\"(authenticated)\") !== -1 || principals.indexOf(username) !== -1));\n}\n\nServer.prototype.requestHandler = function(request,response) {\n\t// Compose the state object\n\tvar self = this;\n\tvar state = {};\n\tstate.wiki = self.wiki;\n\tstate.server = self;\n\tstate.urlInfo = url.parse(request.url);\n\t// Get the principals authorized to access this resource\n\tvar authorizationType = this.methodMappings[request.method] || \"readers\";\n\t// Check for the CSRF header if this is a write\n\tif(!this.csrfDisable && authorizationType === \"writers\" && request.headers[\"x-requested-with\"] !== \"TiddlyWiki\") {\n\t\tresponse.writeHead(403,\"'X-Requested-With' header required to login to '\" + this.servername + \"'\");\n\t\tresponse.end();\n\t\treturn;\t\t\n\t}\n\t// Check whether anonymous access is granted\n\tstate.allowAnon = this.isAuthorized(authorizationType,null);\n\t// Authenticate with the first active authenticator\n\tif(this.authenticators.length > 0) {\n\t\tif(!this.authenticators[0].authenticateRequest(request,response,state)) {\n\t\t\t// Bail if we failed (the authenticator will have sent the response)\n\t\t\treturn;\n\t\t}\t\t\n\t}\n\t// Authorize with the authenticated username\n\tif(!this.isAuthorized(authorizationType,state.authenticatedUsername)) {\n\t\tresponse.writeHead(401,\"'\" + state.authenticatedUsername + \"' is not authorized to access '\" + this.servername + \"'\");\n\t\tresponse.end();\n\t\treturn;\n\t}\n\t// Find the route that matches this path\n\tvar route = self.findMatchingRoute(request,state);\n\t// Optionally output debug info\n\tif(self.get(\"debug-level\") !== \"none\") {\n\t\tconsole.log(\"Request path:\",JSON.stringify(state.urlInfo));\n\t\tconsole.log(\"Request headers:\",JSON.stringify(request.headers));\n\t\tconsole.log(\"authenticatedUsername:\",state.authenticatedUsername);\n\t}\n\t// Return a 404 if we didn't find a route\n\tif(!route) {\n\t\tresponse.writeHead(404);\n\t\tresponse.end();\n\t\treturn;\n\t}\n\t// Receive the request body if necessary and hand off to the route handler\n\tif(route.bodyFormat === \"stream\" || request.method === \"GET\" || request.method === \"HEAD\") {\n\t\t// Let the route handle the request stream itself\n\t\troute.handler(request,response,state);\n\t} else if(route.bodyFormat === \"string\" || !route.bodyFormat) {\n\t\t// Set the encoding for the incoming request\n\t\trequest.setEncoding(\"utf8\");\n\t\tvar data = \"\";\n\t\trequest.on(\"data\",function(chunk) {\n\t\t\tdata += chunk.toString();\n\t\t});\n\t\trequest.on(\"end\",function() {\n\t\t\tstate.data = data;\n\t\t\troute.handler(request,response,state);\n\t\t});\n\t} else if(route.bodyFormat === \"buffer\") {\n\t\tvar data = [];\n\t\trequest.on(\"data\",function(chunk) {\n\t\t\tdata.push(chunk);\n\t\t});\n\t\trequest.on(\"end\",function() {\n\t\t\tstate.data = Buffer.concat(data);\n\t\t\troute.handler(request,response,state);\n\t\t})\n\t} else {\n\t\tresponse.writeHead(400,\"Invalid bodyFormat \" + route.bodyFormat + \" in route \" + route.method + \" \" + route.path.source);\n\t\tresponse.end();\n\t}\n};\n\n/*\nListen for requests\nport: optional port number (falls back to value of \"port\" variable)\nhost: optional host address (falls back to value of \"hist\" variable)\n*/\nServer.prototype.listen = function(port,host) {\n\t// Handle defaults for port and host\n\tport = port || this.get(\"port\");\n\thost = host || this.get(\"host\");\n\t// Check for the port being a string and look it up as an environment variable\n\tif(parseInt(port,10).toString() !== port) {\n\t\tport = process.env[port] || 8080;\n\t}\n\t$tw.utils.log(\"Serving on \" + this.protocol + \"://\" + host + \":\" + port,\"brown/orange\");\n\t$tw.utils.log(\"(press ctrl-C to exit)\",\"red\");\n\t// Warn if required plugins are missing\n\tif(!$tw.wiki.getTiddler(\"$:/plugins/tiddlywiki/tiddlyweb\") || !$tw.wiki.getTiddler(\"$:/plugins/tiddlywiki/filesystem\")) {\n\t\t$tw.utils.warning(\"Warning: Plugins required for client-server operation (\\\"tiddlywiki/filesystem\\\" and \\\"tiddlywiki/tiddlyweb\\\") are missing from tiddlywiki.info file\");\n\t}\n\t// Listen\n\tvar server;\n\tif(this.listenOptions) {\n\t\tserver = this.transport.createServer(this.listenOptions,this.requestHandler.bind(this));\n\t} else {\n\t\tserver = this.transport.createServer(this.requestHandler.bind(this));\n\t}\n\treturn server.listen(port,host);\n};\n\nexports.Server = Server;\n\n})();\n",
"type": "application/javascript",
"module-type": "library"
},
"$:/core/modules/browser-messaging.js": {
"title": "$:/core/modules/browser-messaging.js",
"text": "/*\\\ntitle: $:/core/modules/browser-messaging.js\ntype: application/javascript\nmodule-type: startup\n\nBrowser message handling\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"browser-messaging\";\nexports.platforms = [\"browser\"];\nexports.after = [\"startup\"];\nexports.synchronous = true;\n\n/*\nLoad a specified url as an iframe and call the callback when it is loaded. If the url is already loaded then the existing iframe instance is used\n*/\nfunction loadIFrame(url,callback) {\n\t// Check if iframe already exists\n\tvar iframeInfo = $tw.browserMessaging.iframeInfoMap[url];\n\tif(iframeInfo) {\n\t\t// We've already got the iframe\n\t\tcallback(null,iframeInfo);\n\t} else {\n\t\t// Create the iframe and save it in the list\n\t\tvar iframe = document.createElement(\"iframe\");\n\t\tiframeInfo = {\n\t\t\turl: url,\n\t\t\tstatus: \"loading\",\n\t\t\tdomNode: iframe\n\t\t};\n\t\t$tw.browserMessaging.iframeInfoMap[url] = iframeInfo;\n\t\tsaveIFrameInfoTiddler(iframeInfo);\n\t\t// Add the iframe to the DOM and hide it\n\t\tiframe.style.display = \"none\";\n\t\tiframe.setAttribute(\"library\",\"true\");\n\t\tdocument.body.appendChild(iframe);\n\t\t// Set up onload\n\t\tiframe.onload = function() {\n\t\t\tiframeInfo.status = \"loaded\";\n\t\t\tsaveIFrameInfoTiddler(iframeInfo);\n\t\t\tcallback(null,iframeInfo);\n\t\t};\n\t\tiframe.onerror = function() {\n\t\t\tcallback(\"Cannot load iframe\");\n\t\t};\n\t\ttry {\n\t\t\tiframe.src = url;\n\t\t} catch(ex) {\n\t\t\tcallback(ex);\n\t\t}\n\t}\n}\n\n/*\nUnload library iframe for given url\n*/\nfunction unloadIFrame(url){\n\t$tw.utils.each(document.getElementsByTagName('iframe'), function(iframe) {\n\t\tif(iframe.getAttribute(\"library\") === \"true\" &&\n\t\t iframe.getAttribute(\"src\") === url) {\n\t\t\tiframe.parentNode.removeChild(iframe);\n\t\t}\n\t});\n}\n\nfunction saveIFrameInfoTiddler(iframeInfo) {\n\t$tw.wiki.addTiddler(new $tw.Tiddler($tw.wiki.getCreationFields(),{\n\t\ttitle: \"$:/temp/ServerConnection/\" + iframeInfo.url,\n\t\ttext: iframeInfo.status,\n\t\ttags: [\"$:/tags/ServerConnection\"],\n\t\turl: iframeInfo.url\n\t},$tw.wiki.getModificationFields()));\n}\n\nexports.startup = function() {\n\t// Initialise the store of iframes we've created\n\t$tw.browserMessaging = {\n\t\tiframeInfoMap: {} // Hashmap by URL of {url:,status:\"loading/loaded\",domNode:}\n\t};\n\t// Listen for widget messages to control loading the plugin library\n\t$tw.rootWidget.addEventListener(\"tm-load-plugin-library\",function(event) {\n\t\tvar paramObject = event.paramObject || {},\n\t\t\turl = paramObject.url;\n\t\tif(url) {\n\t\t\tloadIFrame(url,function(err,iframeInfo) {\n\t\t\t\tif(err) {\n\t\t\t\t\talert($tw.language.getString(\"Error/LoadingPluginLibrary\") + \": \" + url);\n\t\t\t\t} else {\n\t\t\t\t\tiframeInfo.domNode.contentWindow.postMessage({\n\t\t\t\t\t\tverb: \"GET\",\n\t\t\t\t\t\turl: \"recipes/library/tiddlers.json\",\n\t\t\t\t\t\tcookies: {\n\t\t\t\t\t\t\ttype: \"save-info\",\n\t\t\t\t\t\t\tinfoTitlePrefix: paramObject.infoTitlePrefix || \"$:/temp/RemoteAssetInfo/\",\n\t\t\t\t\t\t\turl: url\n\t\t\t\t\t\t}\n\t\t\t\t\t},\"*\");\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t});\n\t// Listen for widget messages to control unloading the plugin library\n\t$tw.rootWidget.addEventListener(\"tm-unload-plugin-library\",function(event) {\n\t\tvar paramObject = event.paramObject || {},\n\t\t\turl = paramObject.url;\n\t\t$tw.browserMessaging.iframeInfoMap[url] = undefined;\n\t\tif(url) {\n\t\t\tunloadIFrame(url);\n\t\t\t$tw.utils.each(\n\t\t\t\t$tw.wiki.filterTiddlers(\"[[$:/temp/ServerConnection/\" + url + \"]] [prefix[$:/temp/RemoteAssetInfo/\" + url + \"/]]\"),\n\t\t\t\tfunction(title) {\n\t\t\t\t\t$tw.wiki.deleteTiddler(title);\n\t\t\t\t}\n\t\t\t);\n\t\t}\n\t});\n\t$tw.rootWidget.addEventListener(\"tm-load-plugin-from-library\",function(event) {\n\t\tvar paramObject = event.paramObject || {},\n\t\t\turl = paramObject.url,\n\t\t\ttitle = paramObject.title;\n\t\tif(url && title) {\n\t\t\tloadIFrame(url,function(err,iframeInfo) {\n\t\t\t\tif(err) {\n\t\t\t\t\talert($tw.language.getString(\"Error/LoadingPluginLibrary\") + \": \" + url);\n\t\t\t\t} else {\n\t\t\t\t\tiframeInfo.domNode.contentWindow.postMessage({\n\t\t\t\t\t\tverb: \"GET\",\n\t\t\t\t\t\turl: \"recipes/library/tiddlers/\" + encodeURIComponent(title) + \".json\",\n\t\t\t\t\t\tcookies: {\n\t\t\t\t\t\t\ttype: \"save-tiddler\",\n\t\t\t\t\t\t\turl: url\n\t\t\t\t\t\t}\n\t\t\t\t\t},\"*\");\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t});\n\t// Listen for window messages from other windows\n\twindow.addEventListener(\"message\",function listener(event){\n\t\tconsole.log(\"browser-messaging: \",document.location.toString())\n\t\tconsole.log(\"browser-messaging: Received message from\",event.origin);\n\t\tconsole.log(\"browser-messaging: Message content\",event.data);\n\t\tswitch(event.data.verb) {\n\t\t\tcase \"GET-RESPONSE\":\n\t\t\t\tif(event.data.status.charAt(0) === \"2\") {\n\t\t\t\t\tif(event.data.cookies) {\n\t\t\t\t\t\tif(event.data.cookies.type === \"save-info\") {\n\t\t\t\t\t\t\tvar tiddlers = JSON.parse(event.data.body);\n\t\t\t\t\t\t\t$tw.utils.each(tiddlers,function(tiddler) {\n\t\t\t\t\t\t\t\t$tw.wiki.addTiddler(new $tw.Tiddler($tw.wiki.getCreationFields(),tiddler,{\n\t\t\t\t\t\t\t\t\ttitle: event.data.cookies.infoTitlePrefix + event.data.cookies.url + \"/\" + tiddler.title,\n\t\t\t\t\t\t\t\t\t\"original-title\": tiddler.title,\n\t\t\t\t\t\t\t\t\ttext: \"\",\n\t\t\t\t\t\t\t\t\ttype: \"text/vnd.tiddlywiki\",\n\t\t\t\t\t\t\t\t\t\"original-type\": tiddler.type,\n\t\t\t\t\t\t\t\t\t\"plugin-type\": undefined,\n\t\t\t\t\t\t\t\t\t\"original-plugin-type\": tiddler[\"plugin-type\"],\n\t\t\t\t\t\t\t\t\t\"module-type\": undefined,\n\t\t\t\t\t\t\t\t\t\"original-module-type\": tiddler[\"module-type\"],\n\t\t\t\t\t\t\t\t\ttags: [\"$:/tags/RemoteAssetInfo\"],\n\t\t\t\t\t\t\t\t\t\"original-tags\": $tw.utils.stringifyList(tiddler.tags || []),\n\t\t\t\t\t\t\t\t\t\"server-url\": event.data.cookies.url\n\t\t\t\t\t\t\t\t},$tw.wiki.getModificationFields()));\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} else if(event.data.cookies.type === \"save-tiddler\") {\n\t\t\t\t\t\t\tvar tiddler = JSON.parse(event.data.body);\n\t\t\t\t\t\t\t$tw.wiki.addTiddler(new $tw.Tiddler(tiddler));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t},false);\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "startup"
},
"$:/core/modules/startup/commands.js": {
"title": "$:/core/modules/startup/commands.js",
"text": "/*\\\ntitle: $:/core/modules/startup/commands.js\ntype: application/javascript\nmodule-type: startup\n\nCommand processing\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"commands\";\nexports.platforms = [\"node\"];\nexports.after = [\"story\"];\nexports.synchronous = false;\n\nexports.startup = function(callback) {\n\t// On the server, start a commander with the command line arguments\n\tvar commander = new $tw.Commander(\n\t\t$tw.boot.argv,\n\t\tfunction(err) {\n\t\t\tif(err) {\n\t\t\t\treturn $tw.utils.error(\"Error: \" + err);\n\t\t\t}\n\t\t\tcallback();\n\t\t},\n\t\t$tw.wiki,\n\t\t{output: process.stdout, error: process.stderr}\n\t);\n\tcommander.execute();\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "startup"
},
"$:/core/modules/startup/favicon.js": {
"title": "$:/core/modules/startup/favicon.js",
"text": "/*\\\ntitle: $:/core/modules/startup/favicon.js\ntype: application/javascript\nmodule-type: startup\n\nFavicon handling\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"favicon\";\nexports.platforms = [\"browser\"];\nexports.after = [\"startup\"];\nexports.synchronous = true;\n\t\t\n// Favicon tiddler\nvar FAVICON_TITLE = \"$:/favicon.ico\";\n\nexports.startup = function() {\n\t// Set up the favicon\n\tsetFavicon();\n\t// Reset the favicon when the tiddler changes\n\t$tw.wiki.addEventListener(\"change\",function(changes) {\n\t\tif($tw.utils.hop(changes,FAVICON_TITLE)) {\n\t\t\tsetFavicon();\n\t\t}\n\t});\n};\n\nfunction setFavicon() {\n\tvar tiddler = $tw.wiki.getTiddler(FAVICON_TITLE);\n\tif(tiddler) {\n\t\tvar faviconLink = document.getElementById(\"faviconLink\");\n\t\tfaviconLink.setAttribute(\"href\",\"data:\" + tiddler.fields.type + \";base64,\" + tiddler.fields.text);\n\t}\n}\n\n})();\n",
"type": "application/javascript",
"module-type": "startup"
},
"$:/core/modules/startup/info.js": {
"title": "$:/core/modules/startup/info.js",
"text": "/*\\\ntitle: $:/core/modules/startup/info.js\ntype: application/javascript\nmodule-type: startup\n\nInitialise $:/info tiddlers via $:/temp/info-plugin pseudo-plugin\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"info\";\nexports.before = [\"startup\"];\nexports.after = [\"load-modules\"];\nexports.synchronous = true;\n\nexports.startup = function() {\n\t// Collect up the info tiddlers\n\tvar infoTiddlerFields = {};\n\t// Give each info module a chance to fill in as many info tiddlers as they want\n\t$tw.modules.forEachModuleOfType(\"info\",function(title,moduleExports) {\n\t\tif(moduleExports && moduleExports.getInfoTiddlerFields) {\n\t\t\tvar tiddlerFieldsArray = moduleExports.getInfoTiddlerFields(infoTiddlerFields);\n\t\t\t$tw.utils.each(tiddlerFieldsArray,function(fields) {\n\t\t\t\tif(fields) {\n\t\t\t\t\tinfoTiddlerFields[fields.title] = fields;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t});\n\t// Bake the info tiddlers into a plugin\n\tvar fields = {\n\t\ttitle: \"$:/temp/info-plugin\",\n\t\ttype: \"application/json\",\n\t\t\"plugin-type\": \"info\",\n\t\ttext: JSON.stringify({tiddlers: infoTiddlerFields},null,$tw.config.preferences.jsonSpaces)\n\t};\n\t$tw.wiki.addTiddler(new $tw.Tiddler(fields));\n\t$tw.wiki.readPluginInfo();\n\t$tw.wiki.registerPluginTiddlers(\"info\");\n\t$tw.wiki.unpackPluginTiddlers();\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "startup"
},
"$:/core/modules/startup/load-modules.js": {
"title": "$:/core/modules/startup/load-modules.js",
"text": "/*\\\ntitle: $:/core/modules/startup/load-modules.js\ntype: application/javascript\nmodule-type: startup\n\nLoad core modules\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"load-modules\";\nexports.synchronous = true;\n\nexports.startup = function() {\n\t// Load modules\n\t$tw.modules.applyMethods(\"utils\",$tw.utils);\n\tif($tw.node) {\n\t\t$tw.modules.applyMethods(\"utils-node\",$tw.utils);\n\t}\n\t$tw.modules.applyMethods(\"global\",$tw);\n\t$tw.modules.applyMethods(\"config\",$tw.config);\n\t$tw.Tiddler.fieldModules = $tw.modules.getModulesByTypeAsHashmap(\"tiddlerfield\");\n\t$tw.modules.applyMethods(\"tiddlermethod\",$tw.Tiddler.prototype);\n\t$tw.modules.applyMethods(\"wikimethod\",$tw.Wiki.prototype);\n\t$tw.modules.applyMethods(\"tiddlerdeserializer\",$tw.Wiki.tiddlerDeserializerModules);\n\t$tw.macros = $tw.modules.getModulesByTypeAsHashmap(\"macro\");\n\t$tw.wiki.initParsers();\n\t$tw.Commander.initCommands();\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "startup"
},
"$:/core/modules/startup/password.js": {
"title": "$:/core/modules/startup/password.js",
"text": "/*\\\ntitle: $:/core/modules/startup/password.js\ntype: application/javascript\nmodule-type: startup\n\nPassword handling\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"password\";\nexports.platforms = [\"browser\"];\nexports.after = [\"startup\"];\nexports.synchronous = true;\n\nexports.startup = function() {\n\t$tw.rootWidget.addEventListener(\"tm-set-password\",function(event) {\n\t\t$tw.passwordPrompt.createPrompt({\n\t\t\tserviceName: $tw.language.getString(\"Encryption/PromptSetPassword\"),\n\t\t\tnoUserName: true,\n\t\t\tsubmitText: $tw.language.getString(\"Encryption/SetPassword\"),\n\t\t\tcanCancel: true,\n\t\t\trepeatPassword: true,\n\t\t\tcallback: function(data) {\n\t\t\t\tif(data) {\n\t\t\t\t\t$tw.crypto.setPassword(data.password);\n\t\t\t\t}\n\t\t\t\treturn true; // Get rid of the password prompt\n\t\t\t}\n\t\t});\n\t});\n\t$tw.rootWidget.addEventListener(\"tm-clear-password\",function(event) {\n\t\tif($tw.browser) {\n\t\t\tif(!confirm($tw.language.getString(\"Encryption/ConfirmClearPassword\"))) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\t$tw.crypto.setPassword(null);\n\t});\n\t// Ensure that $:/isEncrypted is maintained properly\n\t$tw.wiki.addEventListener(\"change\",function(changes) {\n\t\tif($tw.utils.hop(changes,\"$:/isEncrypted\")) {\n\t\t\t$tw.crypto.updateCryptoStateTiddler();\n\t\t}\n\t});\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "startup"
},
"$:/core/modules/startup/render.js": {
"title": "$:/core/modules/startup/render.js",
"text": "/*\\\ntitle: $:/core/modules/startup/render.js\ntype: application/javascript\nmodule-type: startup\n\nTitle, stylesheet and page rendering\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"render\";\nexports.platforms = [\"browser\"];\nexports.after = [\"story\"];\nexports.synchronous = true;\n\n// Default story and history lists\nvar PAGE_TITLE_TITLE = \"$:/core/wiki/title\";\nvar PAGE_STYLESHEET_TITLE = \"$:/core/ui/PageStylesheet\";\nvar PAGE_TEMPLATE_TITLE = \"$:/core/ui/PageTemplate\";\n\n// Time (in ms) that we defer refreshing changes to draft tiddlers\nvar DRAFT_TIDDLER_TIMEOUT_TITLE = \"$:/config/Drafts/TypingTimeout\";\nvar DRAFT_TIDDLER_TIMEOUT = 400;\n\nexports.startup = function() {\n\t// Set up the title\n\t$tw.titleWidgetNode = $tw.wiki.makeTranscludeWidget(PAGE_TITLE_TITLE,{document: $tw.fakeDocument, parseAsInline: true});\n\t$tw.titleContainer = $tw.fakeDocument.createElement(\"div\");\n\t$tw.titleWidgetNode.render($tw.titleContainer,null);\n\tdocument.title = $tw.titleContainer.textContent;\n\t$tw.wiki.addEventListener(\"change\",function(changes) {\n\t\tif($tw.titleWidgetNode.refresh(changes,$tw.titleContainer,null)) {\n\t\t\tdocument.title = $tw.titleContainer.textContent;\n\t\t}\n\t});\n\t// Set up the styles\n\t$tw.styleWidgetNode = $tw.wiki.makeTranscludeWidget(PAGE_STYLESHEET_TITLE,{document: $tw.fakeDocument});\n\t$tw.styleContainer = $tw.fakeDocument.createElement(\"style\");\n\t$tw.styleWidgetNode.render($tw.styleContainer,null);\n\t$tw.styleElement = document.createElement(\"style\");\n\t$tw.styleElement.innerHTML = $tw.styleContainer.textContent;\n\tdocument.head.insertBefore($tw.styleElement,document.head.firstChild);\n\t$tw.wiki.addEventListener(\"change\",$tw.perf.report(\"styleRefresh\",function(changes) {\n\t\tif($tw.styleWidgetNode.refresh(changes,$tw.styleContainer,null)) {\n\t\t\t$tw.styleElement.innerHTML = $tw.styleContainer.textContent;\n\t\t}\n\t}));\n\t// Display the $:/core/ui/PageTemplate tiddler to kick off the display\n\t$tw.perf.report(\"mainRender\",function() {\n\t\t$tw.pageWidgetNode = $tw.wiki.makeTranscludeWidget(PAGE_TEMPLATE_TITLE,{document: document, parentWidget: $tw.rootWidget});\n\t\t$tw.pageContainer = document.createElement(\"div\");\n\t\t$tw.utils.addClass($tw.pageContainer,\"tc-page-container-wrapper\");\n\t\tdocument.body.insertBefore($tw.pageContainer,document.body.firstChild);\n\t\t$tw.pageWidgetNode.render($tw.pageContainer,null);\n \t\t$tw.hooks.invokeHook(\"th-page-refreshed\");\n\t})();\n\t// Remove any splash screen elements\n\tvar removeList = document.querySelectorAll(\".tc-remove-when-wiki-loaded\");\n\t$tw.utils.each(removeList,function(removeItem) {\n\t\tif(removeItem.parentNode) {\n\t\t\tremoveItem.parentNode.removeChild(removeItem);\n\t\t}\n\t});\n\t// Prepare refresh mechanism\n\tvar deferredChanges = Object.create(null),\n\t\ttimerId;\n\tfunction refresh() {\n\t\t// Process the refresh\n\t\t$tw.pageWidgetNode.refresh(deferredChanges);\n\t\tdeferredChanges = Object.create(null);\n \t\t$tw.hooks.invokeHook(\"th-page-refreshed\");\n\t}\n\t// Add the change event handler\n\t$tw.wiki.addEventListener(\"change\",$tw.perf.report(\"mainRefresh\",function(changes) {\n\t\t// Check if only drafts have changed\n\t\tvar onlyDraftsHaveChanged = true;\n\t\tfor(var title in changes) {\n\t\t\tvar tiddler = $tw.wiki.getTiddler(title);\n\t\t\tif(!tiddler || !tiddler.hasField(\"draft.of\")) {\n\t\t\t\tonlyDraftsHaveChanged = false;\n\t\t\t}\n\t\t}\n\t\t// Defer the change if only drafts have changed\n\t\tif(timerId) {\n\t\t\tclearTimeout(timerId);\n\t\t}\n\t\ttimerId = null;\n\t\tif(onlyDraftsHaveChanged) {\n\t\t\tvar timeout = parseInt($tw.wiki.getTiddlerText(DRAFT_TIDDLER_TIMEOUT_TITLE,\"\"),10);\n\t\t\tif(isNaN(timeout)) {\n\t\t\t\ttimeout = DRAFT_TIDDLER_TIMEOUT;\n\t\t\t}\n\t\t\ttimerId = setTimeout(refresh,timeout);\n\t\t\t$tw.utils.extend(deferredChanges,changes);\n\t\t} else {\n\t\t\t$tw.utils.extend(deferredChanges,changes);\n\t\t\trefresh();\n\t\t}\n\t}));\n\t// Fix up the link between the root widget and the page container\n\t$tw.rootWidget.domNodes = [$tw.pageContainer];\n\t$tw.rootWidget.children = [$tw.pageWidgetNode];\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "startup"
},
"$:/core/modules/startup/rootwidget.js": {
"title": "$:/core/modules/startup/rootwidget.js",
"text": "/*\\\ntitle: $:/core/modules/startup/rootwidget.js\ntype: application/javascript\nmodule-type: startup\n\nSetup the root widget and the core root widget handlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"rootwidget\";\nexports.platforms = [\"browser\"];\nexports.after = [\"startup\"];\nexports.before = [\"story\"];\nexports.synchronous = true;\n\nexports.startup = function() {\n\t// Install the modal message mechanism\n\t$tw.modal = new $tw.utils.Modal($tw.wiki);\n\t$tw.rootWidget.addEventListener(\"tm-modal\",function(event) {\n\t\t$tw.modal.display(event.param,{variables: event.paramObject, event: event});\n\t});\n\t// Install the notification mechanism\n\t$tw.notifier = new $tw.utils.Notifier($tw.wiki);\n\t$tw.rootWidget.addEventListener(\"tm-notify\",function(event) {\n\t\t$tw.notifier.display(event.param,{variables: event.paramObject});\n\t});\n\t// Install the copy-to-clipboard mechanism\n\t$tw.rootWidget.addEventListener(\"tm-copy-to-clipboard\",function(event) {\n\t\t$tw.utils.copyToClipboard(event.param);\n\t});\n\t// Install the scroller\n\t$tw.pageScroller = new $tw.utils.PageScroller();\n\t$tw.rootWidget.addEventListener(\"tm-scroll\",function(event) {\n\t\t$tw.pageScroller.handleEvent(event);\n\t});\n\tvar fullscreen = $tw.utils.getFullScreenApis();\n\tif(fullscreen) {\n\t\t$tw.rootWidget.addEventListener(\"tm-full-screen\",function(event) {\n\t\t\tif(event.param === \"enter\") {\n\t\t\t\tevent.event.target.ownerDocument.documentElement[fullscreen._requestFullscreen](Element.ALLOW_KEYBOARD_INPUT);\n\t\t\t} else if(event.param === \"exit\") {\n\t\t\t\tevent.event.target.ownerDocument[fullscreen._exitFullscreen]();\n\t\t\t} else {\n\t\t\t\tif(event.event.target.ownerDocument[fullscreen._fullscreenElement]) {\n\t\t\t\t\tevent.event.target.ownerDocument[fullscreen._exitFullscreen]();\n\t\t\t\t} else {\n\t\t\t\t\tevent.event.target.ownerDocument.documentElement[fullscreen._requestFullscreen](Element.ALLOW_KEYBOARD_INPUT);\n\t\t\t\t}\t\t\t\t\n\t\t\t}\n\t\t});\n\t}\n\t// If we're being viewed on a data: URI then give instructions for how to save\n\tif(document.location.protocol === \"data:\") {\n\t\t$tw.rootWidget.dispatchEvent({\n\t\t\ttype: \"tm-modal\",\n\t\t\tparam: \"$:/language/Modals/SaveInstructions\"\n\t\t});\n\t}\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "startup"
},
"$:/core/modules/startup.js": {
"title": "$:/core/modules/startup.js",
"text": "/*\\\ntitle: $:/core/modules/startup.js\ntype: application/javascript\nmodule-type: startup\n\nMiscellaneous startup logic for both the client and server.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"startup\";\nexports.after = [\"load-modules\"];\nexports.synchronous = true;\n\n// Set to `true` to enable performance instrumentation\nvar PERFORMANCE_INSTRUMENTATION_CONFIG_TITLE = \"$:/config/Performance/Instrumentation\";\n\nvar widget = require(\"$:/core/modules/widgets/widget.js\");\n\nexports.startup = function() {\n\tvar modules,n,m,f;\n\t// Minimal browser detection\n\tif($tw.browser) {\n\t\t$tw.browser.isIE = (/msie|trident/i.test(navigator.userAgent));\n\t\t$tw.browser.isFirefox = !!document.mozFullScreenEnabled;\n\t}\n\t// Platform detection\n\t$tw.platform = {};\n\tif($tw.browser) {\n\t\t$tw.platform.isMac = /Mac/.test(navigator.platform);\n\t\t$tw.platform.isWindows = /win/i.test(navigator.platform);\n\t\t$tw.platform.isLinux = /Linux/i.test(navigator.platform);\n\t} else {\n\t\tswitch(require(\"os\").platform()) {\n\t\t\tcase \"darwin\":\n\t\t\t\t$tw.platform.isMac = true;\n\t\t\t\tbreak;\n\t\t\tcase \"win32\":\n\t\t\t\t$tw.platform.isWindows = true;\n\t\t\t\tbreak;\n\t\t\tcase \"freebsd\":\n\t\t\t\t$tw.platform.isLinux = true;\n\t\t\t\tbreak;\n\t\t\tcase \"linux\":\n\t\t\t\t$tw.platform.isLinux = true;\n\t\t\t\tbreak;\n\t\t}\n\t}\n\t// Initialise version\n\t$tw.version = $tw.utils.extractVersionInfo();\n\t// Set up the performance framework\n\t$tw.perf = new $tw.Performance($tw.wiki.getTiddlerText(PERFORMANCE_INSTRUMENTATION_CONFIG_TITLE,\"no\") === \"yes\");\n\t// Kick off the language manager and switcher\n\t$tw.language = new $tw.Language();\n\t$tw.languageSwitcher = new $tw.PluginSwitcher({\n\t\twiki: $tw.wiki,\n\t\tpluginType: \"language\",\n\t\tcontrollerTitle: \"$:/language\",\n\t\tdefaultPlugins: [\n\t\t\t\"$:/languages/en-US\"\n\t\t],\n\t\tonSwitch: function(plugins) {\n\t\t\tif($tw.browser) {\n\t\t\t\tvar pluginTiddler = $tw.wiki.getTiddler(plugins[0]);\n\t\t\t\tif(pluginTiddler) {\n\t\t\t\t\tdocument.documentElement.setAttribute(\"dir\",pluginTiddler.getFieldString(\"text-direction\") || \"auto\");\n\t\t\t\t} else {\n\t\t\t\t\tdocument.documentElement.removeAttribute(\"dir\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n\t// Kick off the theme manager\n\t$tw.themeManager = new $tw.PluginSwitcher({\n\t\twiki: $tw.wiki,\n\t\tpluginType: \"theme\",\n\t\tcontrollerTitle: \"$:/theme\",\n\t\tdefaultPlugins: [\n\t\t\t\"$:/themes/tiddlywiki/snowwhite\",\n\t\t\t\"$:/themes/tiddlywiki/vanilla\"\n\t\t]\n\t});\n\t// Kick off the keyboard manager\n\t$tw.keyboardManager = new $tw.KeyboardManager();\n\t// Listen for shortcuts\n\tif($tw.browser) {\n\t\t$tw.utils.addEventListeners(document,[{\n\t\t\tname: \"keydown\",\n\t\t\thandlerObject: $tw.keyboardManager,\n\t\t\thandlerMethod: \"handleKeydownEvent\"\n\t\t}]);\n\t}\n\t// Create a root widget for attaching event handlers. By using it as the parentWidget for another widget tree, one can reuse the event handlers\n\t$tw.rootWidget = new widget.widget({\n\t\ttype: \"widget\",\n\t\tchildren: []\n\t},{\n\t\twiki: $tw.wiki,\n\t\tdocument: $tw.browser ? document : $tw.fakeDocument\n\t});\n\t// Execute any startup actions\n\tvar executeStartupTiddlers = function(tag) {\n\t\t$tw.utils.each($tw.wiki.filterTiddlers(\"[all[shadows+tiddlers]tag[\" + tag + \"]!has[draft.of]]\"),function(title) {\n\t\t\t$tw.rootWidget.invokeActionString($tw.wiki.getTiddlerText(title),$tw.rootWidget);\n\t\t});\n\t};\n\texecuteStartupTiddlers(\"$:/tags/StartupAction\");\n\tif($tw.browser) {\n\t\texecuteStartupTiddlers(\"$:/tags/StartupAction/Browser\");\t\t\n\t}\n\tif($tw.node) {\n\t\texecuteStartupTiddlers(\"$:/tags/StartupAction/Node\");\t\t\n\t}\n\t// Clear outstanding tiddler store change events to avoid an unnecessary refresh cycle at startup\n\t$tw.wiki.clearTiddlerEventQueue();\n\t// Find a working syncadaptor\n\t$tw.syncadaptor = undefined;\n\t$tw.modules.forEachModuleOfType(\"syncadaptor\",function(title,module) {\n\t\tif(!$tw.syncadaptor && module.adaptorClass) {\n\t\t\t$tw.syncadaptor = new module.adaptorClass({wiki: $tw.wiki});\n\t\t}\n\t});\n\t// Set up the syncer object if we've got a syncadaptor\n\tif($tw.syncadaptor) {\n\t\t$tw.syncer = new $tw.Syncer({wiki: $tw.wiki, syncadaptor: $tw.syncadaptor});\n\t} \n\t// Setup the saver handler\n\t$tw.saverHandler = new $tw.SaverHandler({wiki: $tw.wiki, dirtyTracking: !$tw.syncadaptor});\n\t// Host-specific startup\n\tif($tw.browser) {\n\t\t// Install the popup manager\n\t\t$tw.popup = new $tw.utils.Popup();\n\t\t// Install the animator\n\t\t$tw.anim = new $tw.utils.Animator();\n\t}\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "startup"
},
"$:/core/modules/startup/story.js": {
"title": "$:/core/modules/startup/story.js",
"text": "/*\\\ntitle: $:/core/modules/startup/story.js\ntype: application/javascript\nmodule-type: startup\n\nLoad core modules\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"story\";\nexports.after = [\"startup\"];\nexports.synchronous = true;\n\n// Default story and history lists\nvar DEFAULT_STORY_TITLE = \"$:/StoryList\";\nvar DEFAULT_HISTORY_TITLE = \"$:/HistoryList\";\n\n// Default tiddlers\nvar DEFAULT_TIDDLERS_TITLE = \"$:/DefaultTiddlers\";\n\n// Config\nvar CONFIG_UPDATE_ADDRESS_BAR = \"$:/config/Navigation/UpdateAddressBar\"; // Can be \"no\", \"permalink\", \"permaview\"\nvar CONFIG_UPDATE_HISTORY = \"$:/config/Navigation/UpdateHistory\"; // Can be \"yes\" or \"no\"\nvar CONFIG_PERMALINKVIEW_COPY_TO_CLIPBOARD = \"$:/config/Navigation/Permalinkview/CopyToClipboard\"; // Can be \"yes\" (default) or \"no\"\nvar CONFIG_PERMALINKVIEW_UPDATE_ADDRESS_BAR = \"$:/config/Navigation/Permalinkview/UpdateAddressBar\"; // Can be \"yes\" (default) or \"no\"\n\n\n// Links to help, if there is no param\nvar HELP_OPEN_EXTERNAL_WINDOW = \"http://tiddlywiki.com/#WidgetMessage%3A%20tm-open-external-window\";\n\nexports.startup = function() {\n\t// Open startup tiddlers\n\topenStartupTiddlers();\n\tif($tw.browser) {\n\t\t// Set up location hash update\n\t\t$tw.wiki.addEventListener(\"change\",function(changes) {\n\t\t\tif($tw.utils.hop(changes,DEFAULT_STORY_TITLE) || $tw.utils.hop(changes,DEFAULT_HISTORY_TITLE)) {\n\t\t\t\tupdateLocationHash({\n\t\t\t\t\tupdateAddressBar: $tw.wiki.getTiddlerText(CONFIG_UPDATE_ADDRESS_BAR,\"permaview\").trim(),\n\t\t\t\t\tupdateHistory: $tw.wiki.getTiddlerText(CONFIG_UPDATE_HISTORY,\"no\").trim()\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\t\t// Listen for changes to the browser location hash\n\t\twindow.addEventListener(\"hashchange\",function() {\n\t\t\tvar hash = $tw.utils.getLocationHash();\n\t\t\tif(hash !== $tw.locationHash) {\n\t\t\t\t$tw.locationHash = hash;\n\t\t\t\topenStartupTiddlers({defaultToCurrentStory: true});\n\t\t\t}\n\t\t},false);\n\t\t// Listen for the tm-browser-refresh message\n\t\t$tw.rootWidget.addEventListener(\"tm-browser-refresh\",function(event) {\n\t\t\twindow.location.reload(true);\n\t\t});\n\t\t// Listen for tm-open-external-window message\n\t\t$tw.rootWidget.addEventListener(\"tm-open-external-window\",function(event) {\n\t\t\tvar paramObject = event.paramObject || {},\n\t\t\t\tstrUrl = event.param || HELP_OPEN_EXTERNAL_WINDOW,\n\t\t\t\tstrWindowName = paramObject.windowName,\n\t\t\t\tstrWindowFeatures = paramObject.windowFeatures;\n\t\t\twindow.open(strUrl, strWindowName, strWindowFeatures);\n\t\t});\n\t\t// Listen for the tm-print message\n\t\t$tw.rootWidget.addEventListener(\"tm-print\",function(event) {\n\t\t\t(event.event.view || window).print();\n\t\t});\n\t\t// Listen for the tm-home message\n\t\t$tw.rootWidget.addEventListener(\"tm-home\",function(event) {\n\t\t\twindow.location.hash = \"\";\n\t\t\tvar storyFilter = $tw.wiki.getTiddlerText(DEFAULT_TIDDLERS_TITLE),\n\t\t\t\tstoryList = $tw.wiki.filterTiddlers(storyFilter);\n\t\t\t//invoke any hooks that might change the default story list\n\t\t\tstoryList = $tw.hooks.invokeHook(\"th-opening-default-tiddlers-list\",storyList);\n\t\t\t$tw.wiki.addTiddler({title: DEFAULT_STORY_TITLE, text: \"\", list: storyList},$tw.wiki.getModificationFields());\n\t\t\tif(storyList[0]) {\n\t\t\t\t$tw.wiki.addToHistory(storyList[0]);\n\t\t\t}\n\t\t});\n\t\t// Listen for the tm-permalink message\n\t\t$tw.rootWidget.addEventListener(\"tm-permalink\",function(event) {\n\t\t\tupdateLocationHash({\n\t\t\t\tupdateAddressBar: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_UPDATE_ADDRESS_BAR,\"yes\").trim() === \"yes\" ? \"permalink\" : \"none\",\n\t\t\t\tupdateHistory: $tw.wiki.getTiddlerText(CONFIG_UPDATE_HISTORY,\"no\").trim(),\n\t\t\t\ttargetTiddler: event.param || event.tiddlerTitle,\n\t\t\t\tcopyToClipboard: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_COPY_TO_CLIPBOARD,\"yes\").trim() === \"yes\" ? \"permalink\" : \"none\"\n\t\t\t});\n\t\t});\n\t\t// Listen for the tm-permaview message\n\t\t$tw.rootWidget.addEventListener(\"tm-permaview\",function(event) {\n\t\t\tupdateLocationHash({\n\t\t\t\tupdateAddressBar: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_UPDATE_ADDRESS_BAR,\"yes\").trim() === \"yes\" ? \"permaview\" : \"none\",\n\t\t\t\tupdateHistory: $tw.wiki.getTiddlerText(CONFIG_UPDATE_HISTORY,\"no\").trim(),\n\t\t\t\ttargetTiddler: event.param || event.tiddlerTitle,\n\t\t\t\tcopyToClipboard: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_COPY_TO_CLIPBOARD,\"yes\").trim() === \"yes\" ? \"permaview\" : \"none\"\n\t\t\t});\t\t\t\t\n\t\t});\n\t}\n};\n\n/*\nProcess the location hash to open the specified tiddlers. Options:\ndefaultToCurrentStory: If true, the current story is retained as the default, instead of opening the default tiddlers\n*/\nfunction openStartupTiddlers(options) {\n\toptions = options || {};\n\t// Work out the target tiddler and the story filter. \"null\" means \"unspecified\"\n\tvar target = null,\n\t\tstoryFilter = null;\n\tif($tw.locationHash.length > 1) {\n\t\tvar hash = $tw.locationHash.substr(1),\n\t\t\tsplit = hash.indexOf(\":\");\n\t\tif(split === -1) {\n\t\t\ttarget = decodeURIComponent(hash.trim());\n\t\t} else {\n\t\t\ttarget = decodeURIComponent(hash.substr(0,split).trim());\n\t\t\tstoryFilter = decodeURIComponent(hash.substr(split + 1).trim());\n\t\t}\n\t}\n\t// If the story wasn't specified use the current tiddlers or a blank story\n\tif(storyFilter === null) {\n\t\tif(options.defaultToCurrentStory) {\n\t\t\tvar currStoryList = $tw.wiki.getTiddlerList(DEFAULT_STORY_TITLE);\n\t\t\tstoryFilter = $tw.utils.stringifyList(currStoryList);\n\t\t} else {\n\t\t\tif(target && target !== \"\") {\n\t\t\t\tstoryFilter = \"\";\n\t\t\t} else {\n\t\t\t\tstoryFilter = $tw.wiki.getTiddlerText(DEFAULT_TIDDLERS_TITLE);\n\t\t\t}\n\t\t}\n\t}\n\t// Process the story filter to get the story list\n\tvar storyList = $tw.wiki.filterTiddlers(storyFilter);\n\t// Invoke any hooks that want to change the default story list\n\tstoryList = $tw.hooks.invokeHook(\"th-opening-default-tiddlers-list\",storyList);\n\t// If the target tiddler isn't included then splice it in at the top\n\tif(target && storyList.indexOf(target) === -1) {\n\t\tstoryList.unshift(target);\n\t}\n\t// Save the story list\n\t$tw.wiki.addTiddler({title: DEFAULT_STORY_TITLE, text: \"\", list: storyList},$tw.wiki.getModificationFields());\n\t// If a target tiddler was specified add it to the history stack\n\tif(target && target !== \"\") {\n\t\t// The target tiddler doesn't need double square brackets, but we'll silently remove them if they're present\n\t\tif(target.indexOf(\"[[\") === 0 && target.substr(-2) === \"]]\") {\n\t\t\ttarget = target.substr(2,target.length - 4);\n\t\t}\n\t\t$tw.wiki.addToHistory(target);\n\t} else if(storyList.length > 0) {\n\t\t$tw.wiki.addToHistory(storyList[0]);\n\t}\n}\n\n/*\noptions: See below\noptions.updateAddressBar: \"permalink\", \"permaview\" or \"no\" (defaults to \"permaview\")\noptions.updateHistory: \"yes\" or \"no\" (defaults to \"no\")\noptions.copyToClipboard: \"permalink\", \"permaview\" or \"no\" (defaults to \"no\")\noptions.targetTiddler: optional title of target tiddler for permalink\n*/\nfunction updateLocationHash(options) {\n\t// Get the story and the history stack\n\tvar storyList = $tw.wiki.getTiddlerList(DEFAULT_STORY_TITLE),\n\t\thistoryList = $tw.wiki.getTiddlerData(DEFAULT_HISTORY_TITLE,[]),\n\t\ttargetTiddler = \"\";\n\tif(options.targetTiddler) {\n\t\ttargetTiddler = options.targetTiddler;\n\t} else {\n\t\t// The target tiddler is the one at the top of the stack\n\t\tif(historyList.length > 0) {\n\t\t\ttargetTiddler = historyList[historyList.length-1].title;\n\t\t}\n\t\t// Blank the target tiddler if it isn't present in the story\n\t\tif(storyList.indexOf(targetTiddler) === -1) {\n\t\t\ttargetTiddler = \"\";\n\t\t}\n\t}\n\t// Assemble the location hash\n\tswitch(options.updateAddressBar) {\n\t\tcase \"permalink\":\n\t\t\t$tw.locationHash = \"#\" + encodeURIComponent(targetTiddler);\n\t\t\tbreak;\n\t\tcase \"permaview\":\n\t\t\t$tw.locationHash = \"#\" + encodeURIComponent(targetTiddler) + \":\" + encodeURIComponent($tw.utils.stringifyList(storyList));\n\t\t\tbreak;\n\t}\n\t// Copy URL to the clipboard\n\tswitch(options.copyToClipboard) {\n\t\tcase \"permalink\":\n\t\t\t$tw.utils.copyToClipboard($tw.utils.getLocationPath() + \"#\" + encodeURIComponent(targetTiddler));\n\t\t\tbreak;\n\t\tcase \"permaview\":\n\t\t\t$tw.utils.copyToClipboard($tw.utils.getLocationPath() + \"#\" + encodeURIComponent(targetTiddler) + \":\" + encodeURIComponent($tw.utils.stringifyList(storyList)));\n\t\t\tbreak;\n\t}\n\t// Only change the location hash if we must, thus avoiding unnecessary onhashchange events\n\tif($tw.utils.getLocationHash() !== $tw.locationHash) {\n\t\tif(options.updateHistory === \"yes\") {\n\t\t\t// Assign the location hash so that history is updated\n\t\t\twindow.location.hash = $tw.locationHash;\n\t\t} else {\n\t\t\t// We use replace so that browser history isn't affected\n\t\t\twindow.location.replace(window.location.toString().split(\"#\")[0] + $tw.locationHash);\n\t\t}\n\t}\n}\n\n})();\n",
"type": "application/javascript",
"module-type": "startup"
},
"$:/core/modules/startup/windows.js": {
"title": "$:/core/modules/startup/windows.js",
"text": "/*\\\ntitle: $:/core/modules/startup/windows.js\ntype: application/javascript\nmodule-type: startup\n\nSetup root widget handlers for the messages concerned with opening external browser windows\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"windows\";\nexports.platforms = [\"browser\"];\nexports.after = [\"startup\"];\nexports.synchronous = true;\n\n// Global to keep track of open windows (hashmap by title)\nvar windows = {};\n\nexports.startup = function() {\n\t// Handle open window message\n\t$tw.rootWidget.addEventListener(\"tm-open-window\",function(event) {\n\t\t// Get the parameters\n\t\tvar refreshHandler,\n\t\t\ttitle = event.param || event.tiddlerTitle,\n\t\t\tparamObject = event.paramObject || {},\n\t\t\ttemplate = paramObject.template || \"$:/core/templates/single.tiddler.window\",\n\t\t\twidth = paramObject.width || \"700\",\n\t\t\theight = paramObject.height || \"600\",\n\t\t\tvariables = $tw.utils.extend({},paramObject,{currentTiddler: title});\n\t\t// Open the window\n\t\tvar srcWindow,\n\t\t srcDocument;\n\t\t// In case that popup blockers deny opening a new window\n\t\ttry {\n\t\t\tsrcWindow = window.open(\"\",\"external-\" + title,\"scrollbars,width=\" + width + \",height=\" + height),\n\t\t\tsrcDocument = srcWindow.document;\n\t\t}\n\t\tcatch(e) {\n\t\t\treturn;\n\t\t}\n\t\twindows[title] = srcWindow;\n\t\t// Check for reopening the same window\n\t\tif(srcWindow.haveInitialisedWindow) {\n\t\t\treturn;\n\t\t}\n\t\t// Initialise the document\n\t\tsrcDocument.write(\"<html><head></head><body class='tc-body tc-single-tiddler-window'></body></html>\");\n\t\tsrcDocument.close();\n\t\tsrcDocument.title = title;\n\t\tsrcWindow.addEventListener(\"beforeunload\",function(event) {\n\t\t\tdelete windows[title];\n\t\t\t$tw.wiki.removeEventListener(\"change\",refreshHandler);\n\t\t},false);\n\t\t// Set up the styles\n\t\tvar styleWidgetNode = $tw.wiki.makeTranscludeWidget(\"$:/core/ui/PageStylesheet\",{\n\t\t\t\tdocument: $tw.fakeDocument,\n\t\t\t\tvariables: variables,\n\t\t\t\timportPageMacros: true}),\n\t\t\tstyleContainer = $tw.fakeDocument.createElement(\"style\");\n\t\tstyleWidgetNode.render(styleContainer,null);\n\t\tvar styleElement = srcDocument.createElement(\"style\");\n\t\tstyleElement.innerHTML = styleContainer.textContent;\n\t\tsrcDocument.head.insertBefore(styleElement,srcDocument.head.firstChild);\n\t\t// Render the text of the tiddler\n\t\tvar parser = $tw.wiki.parseTiddler(template),\n\t\t\twidgetNode = $tw.wiki.makeWidget(parser,{document: srcDocument, parentWidget: $tw.rootWidget, variables: variables});\n\t\twidgetNode.render(srcDocument.body,srcDocument.body.firstChild);\n\t\t// Function to handle refreshes\n\t\trefreshHandler = function(changes) {\n\t\t\tif(styleWidgetNode.refresh(changes,styleContainer,null)) {\n\t\t\t\tstyleElement.innerHTML = styleContainer.textContent;\n\t\t\t}\n\t\t\twidgetNode.refresh(changes);\n\t\t};\n\t\t$tw.wiki.addEventListener(\"change\",refreshHandler);\n\t\t// Listen for keyboard shortcuts\n\t\t$tw.utils.addEventListeners(srcDocument,[{\n\t\t\tname: \"keydown\",\n\t\t\thandlerObject: $tw.keyboardManager,\n\t\t\thandlerMethod: \"handleKeydownEvent\"\n\t\t},{\n\t\t\tname: \"click\",\n\t\t\thandlerObject: $tw.popup,\n\t\t\thandlerMethod: \"handleEvent\"\n\t\t}]);\n\t\tsrcWindow.haveInitialisedWindow = true;\n\t});\n\t// Close open windows when unloading main window\n\t$tw.addUnloadTask(function() {\n\t\t$tw.utils.each(windows,function(win) {\n\t\t\twin.close();\n\t\t});\n\t});\n\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "startup"
},
"$:/core/modules/story.js": {
"title": "$:/core/modules/story.js",
"text": "/*\\\ntitle: $:/core/modules/story.js\ntype: application/javascript\nmodule-type: global\n\nLightweight object for managing interactions with the story and history lists.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nConstruct Story object with options:\nwiki: reference to wiki object to use to resolve tiddler titles\nstoryTitle: title of story list tiddler\nhistoryTitle: title of history list tiddler\n*/\nfunction Story(options) {\n\toptions = options || {};\n\tthis.wiki = options.wiki || $tw.wiki;\n\tthis.storyTitle = options.storyTitle || \"$:/StoryList\";\n\tthis.historyTitle = options.historyTitle || \"$:/HistoryList\";\n};\n\nStory.prototype.navigateTiddler = function(navigateTo,navigateFromTitle,navigateFromClientRect) {\n\tthis.addToStory(navigateTo,navigateFromTitle);\n\tthis.addToHistory(navigateTo,navigateFromClientRect);\n};\n\nStory.prototype.getStoryList = function() {\n\treturn this.wiki.getTiddlerList(this.storyTitle) || [];\n};\n\nStory.prototype.addToStory = function(navigateTo,navigateFromTitle,options) {\n\toptions = options || {};\n\tvar storyList = this.getStoryList();\n\t// See if the tiddler is already there\n\tvar slot = storyList.indexOf(navigateTo);\n\t// Quit if it already exists in the story river\n\tif(slot >= 0) {\n\t\treturn;\n\t}\n\t// First we try to find the position of the story element we navigated from\n\tvar fromIndex = storyList.indexOf(navigateFromTitle);\n\tif(fromIndex >= 0) {\n\t\t// The tiddler is added from inside the river\n\t\t// Determine where to insert the tiddler; Fallback is \"below\"\n\t\tswitch(options.openLinkFromInsideRiver) {\n\t\t\tcase \"top\":\n\t\t\t\tslot = 0;\n\t\t\t\tbreak;\n\t\t\tcase \"bottom\":\n\t\t\t\tslot = storyList.length;\n\t\t\t\tbreak;\n\t\t\tcase \"above\":\n\t\t\t\tslot = fromIndex;\n\t\t\t\tbreak;\n\t\t\tcase \"below\": // Intentional fall-through\n\t\t\tdefault:\n\t\t\t\tslot = fromIndex + 1;\n\t\t\t\tbreak;\n\t\t}\n\t} else {\n\t\t// The tiddler is opened from outside the river. Determine where to insert the tiddler; default is \"top\"\n\t\tif(options.openLinkFromOutsideRiver === \"bottom\") {\n\t\t\t// Insert at bottom\n\t\t\tslot = storyList.length;\n\t\t} else {\n\t\t\t// Insert at top\n\t\t\tslot = 0;\n\t\t}\n\t}\n\t// Add the tiddler\n\tstoryList.splice(slot,0,navigateTo);\n\t// Save the story\n\tthis.saveStoryList(storyList);\n};\n\nStory.prototype.saveStoryList = function(storyList) {\n\tvar storyTiddler = this.wiki.getTiddler(this.storyTitle);\n\tthis.wiki.addTiddler(new $tw.Tiddler(\n\t\tthis.wiki.getCreationFields(),\n\t\t{title: this.storyTitle},\n\t\tstoryTiddler,\n\t\t{list: storyList},\n\t\tthis.wiki.getModificationFields()\n\t));\n};\n\nStory.prototype.addToHistory = function(navigateTo,navigateFromClientRect) {\n\tvar titles = $tw.utils.isArray(navigateTo) ? navigateTo : [navigateTo];\n\t// Add a new record to the top of the history stack\n\tvar historyList = this.wiki.getTiddlerData(this.historyTitle,[]);\n\t$tw.utils.each(titles,function(title) {\n\t\thistoryList.push({title: title, fromPageRect: navigateFromClientRect});\n\t});\n\tthis.wiki.setTiddlerData(this.historyTitle,historyList,{\"current-tiddler\": titles[titles.length-1]});\n};\n\nStory.prototype.storyCloseTiddler = function(targetTitle) {\n// TBD\n};\n\nStory.prototype.storyCloseAllTiddlers = function() {\n// TBD\n};\n\nStory.prototype.storyCloseOtherTiddlers = function(targetTitle) {\n// TBD\n};\n\nStory.prototype.storyEditTiddler = function(targetTitle) {\n// TBD\n};\n\nStory.prototype.storyDeleteTiddler = function(targetTitle) {\n// TBD\n};\n\nStory.prototype.storySaveTiddler = function(targetTitle) {\n// TBD\n};\n\nStory.prototype.storyCancelTiddler = function(targetTitle) {\n// TBD\n};\n\nStory.prototype.storyNewTiddler = function(targetTitle) {\n// TBD\n};\n\nexports.Story = Story;\n\n\n})();\n",
"type": "application/javascript",
"module-type": "global"
},
"$:/core/modules/storyviews/classic.js": {
"title": "$:/core/modules/storyviews/classic.js",
"text": "/*\\\ntitle: $:/core/modules/storyviews/classic.js\ntype: application/javascript\nmodule-type: storyview\n\nViews the story as a linear sequence\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar easing = \"cubic-bezier(0.645, 0.045, 0.355, 1)\"; // From http://easings.net/#easeInOutCubic\n\nvar ClassicStoryView = function(listWidget) {\n\tthis.listWidget = listWidget;\n};\n\nClassicStoryView.prototype.navigateTo = function(historyInfo) {\n\tvar listElementIndex = this.listWidget.findListItem(0,historyInfo.title);\n\tif(listElementIndex === undefined) {\n\t\treturn;\n\t}\n\tvar listItemWidget = this.listWidget.children[listElementIndex],\n\t\ttargetElement = listItemWidget.findFirstDomNode();\n\t// Abandon if the list entry isn't a DOM element (it might be a text node)\n\tif(!(targetElement instanceof Element)) {\n\t\treturn;\n\t}\n\t// Scroll the node into view\n\tthis.listWidget.dispatchEvent({type: \"tm-scroll\", target: targetElement});\n};\n\nClassicStoryView.prototype.insert = function(widget) {\n\tvar targetElement = widget.findFirstDomNode(),\n\t\tduration = $tw.utils.getAnimationDuration();\n\t// Abandon if the list entry isn't a DOM element (it might be a text node)\n\tif(!(targetElement instanceof Element)) {\n\t\treturn;\n\t}\n\t// Get the current height of the tiddler\n\tvar computedStyle = window.getComputedStyle(targetElement),\n\t\tcurrMarginBottom = parseInt(computedStyle.marginBottom,10),\n\t\tcurrMarginTop = parseInt(computedStyle.marginTop,10),\n\t\tcurrHeight = targetElement.offsetHeight + currMarginTop;\n\t// Reset the margin once the transition is over\n\tsetTimeout(function() {\n\t\t$tw.utils.setStyle(targetElement,[\n\t\t\t{transition: \"none\"},\n\t\t\t{marginBottom: \"\"}\n\t\t]);\n\t},duration);\n\t// Set up the initial position of the element\n\t$tw.utils.setStyle(targetElement,[\n\t\t{transition: \"none\"},\n\t\t{marginBottom: (-currHeight) + \"px\"},\n\t\t{opacity: \"0.0\"}\n\t]);\n\t$tw.utils.forceLayout(targetElement);\n\t// Transition to the final position\n\t$tw.utils.setStyle(targetElement,[\n\t\t{transition: \"opacity \" + duration + \"ms \" + easing + \", \" +\n\t\t\t\t\t\"margin-bottom \" + duration + \"ms \" + easing},\n\t\t{marginBottom: currMarginBottom + \"px\"},\n\t\t{opacity: \"1.0\"}\n\t]);\n};\n\nClassicStoryView.prototype.remove = function(widget) {\n\tvar targetElement = widget.findFirstDomNode(),\n\t\tduration = $tw.utils.getAnimationDuration(),\n\t\tremoveElement = function() {\n\t\t\twidget.removeChildDomNodes();\n\t\t};\n\t// Abandon if the list entry isn't a DOM element (it might be a text node)\n\tif(!(targetElement instanceof Element)) {\n\t\tremoveElement();\n\t\treturn;\n\t}\n\t// Get the current height of the tiddler\n\tvar currWidth = targetElement.offsetWidth,\n\t\tcomputedStyle = window.getComputedStyle(targetElement),\n\t\tcurrMarginBottom = parseInt(computedStyle.marginBottom,10),\n\t\tcurrMarginTop = parseInt(computedStyle.marginTop,10),\n\t\tcurrHeight = targetElement.offsetHeight + currMarginTop;\n\t// Remove the dom nodes of the widget at the end of the transition\n\tsetTimeout(removeElement,duration);\n\t// Animate the closure\n\t$tw.utils.setStyle(targetElement,[\n\t\t{transition: \"none\"},\n\t\t{transform: \"translateX(0px)\"},\n\t\t{marginBottom: currMarginBottom + \"px\"},\n\t\t{opacity: \"1.0\"}\n\t]);\n\t$tw.utils.forceLayout(targetElement);\n\t$tw.utils.setStyle(targetElement,[\n\t\t{transition: $tw.utils.roundTripPropertyName(\"transform\") + \" \" + duration + \"ms \" + easing + \", \" +\n\t\t\t\t\t\"opacity \" + duration + \"ms \" + easing + \", \" +\n\t\t\t\t\t\"margin-bottom \" + duration + \"ms \" + easing},\n\t\t{transform: \"translateX(-\" + currWidth + \"px)\"},\n\t\t{marginBottom: (-currHeight) + \"px\"},\n\t\t{opacity: \"0.0\"}\n\t]);\n};\n\nexports.classic = ClassicStoryView;\n\n})();",
"type": "application/javascript",
"module-type": "storyview"
},
"$:/core/modules/storyviews/pop.js": {
"title": "$:/core/modules/storyviews/pop.js",
"text": "/*\\\ntitle: $:/core/modules/storyviews/pop.js\ntype: application/javascript\nmodule-type: storyview\n\nAnimates list insertions and removals\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar PopStoryView = function(listWidget) {\n\tthis.listWidget = listWidget;\n};\n\nPopStoryView.prototype.navigateTo = function(historyInfo) {\n\tvar listElementIndex = this.listWidget.findListItem(0,historyInfo.title);\n\tif(listElementIndex === undefined) {\n\t\treturn;\n\t}\n\tvar listItemWidget = this.listWidget.children[listElementIndex],\n\t\ttargetElement = listItemWidget.findFirstDomNode();\n\t// Abandon if the list entry isn't a DOM element (it might be a text node)\n\tif(!(targetElement instanceof Element)) {\n\t\treturn;\n\t}\n\t// Scroll the node into view\n\tthis.listWidget.dispatchEvent({type: \"tm-scroll\", target: targetElement});\n};\n\nPopStoryView.prototype.insert = function(widget) {\n\tvar targetElement = widget.findFirstDomNode(),\n\t\tduration = $tw.utils.getAnimationDuration();\n\t// Abandon if the list entry isn't a DOM element (it might be a text node)\n\tif(!(targetElement instanceof Element)) {\n\t\treturn;\n\t}\n\t// Reset once the transition is over\n\tsetTimeout(function() {\n\t\t$tw.utils.setStyle(targetElement,[\n\t\t\t{transition: \"none\"},\n\t\t\t{transform: \"none\"}\n\t\t]);\n\t},duration);\n\t// Set up the initial position of the element\n\t$tw.utils.setStyle(targetElement,[\n\t\t{transition: \"none\"},\n\t\t{transform: \"scale(2)\"},\n\t\t{opacity: \"0.0\"}\n\t]);\n\t$tw.utils.forceLayout(targetElement);\n\t// Transition to the final position\n\t$tw.utils.setStyle(targetElement,[\n\t\t{transition: $tw.utils.roundTripPropertyName(\"transform\") + \" \" + duration + \"ms ease-in-out, \" +\n\t\t\t\t\t\"opacity \" + duration + \"ms ease-in-out\"},\n\t\t{transform: \"scale(1)\"},\n\t\t{opacity: \"1.0\"}\n\t]);\n};\n\nPopStoryView.prototype.remove = function(widget) {\n\tvar targetElement = widget.findFirstDomNode(),\n\t\tduration = $tw.utils.getAnimationDuration(),\n\t\tremoveElement = function() {\n\t\t\tif(targetElement.parentNode) {\n\t\t\t\twidget.removeChildDomNodes();\n\t\t\t}\n\t\t};\n\t// Abandon if the list entry isn't a DOM element (it might be a text node)\n\tif(!(targetElement instanceof Element)) {\n\t\tremoveElement();\n\t\treturn;\n\t}\n\t// Remove the element at the end of the transition\n\tsetTimeout(removeElement,duration);\n\t// Animate the closure\n\t$tw.utils.setStyle(targetElement,[\n\t\t{transition: \"none\"},\n\t\t{transform: \"scale(1)\"},\n\t\t{opacity: \"1.0\"}\n\t]);\n\t$tw.utils.forceLayout(targetElement);\n\t$tw.utils.setStyle(targetElement,[\n\t\t{transition: $tw.utils.roundTripPropertyName(\"transform\") + \" \" + duration + \"ms ease-in-out, \" +\n\t\t\t\t\t\"opacity \" + duration + \"ms ease-in-out\"},\n\t\t{transform: \"scale(0.1)\"},\n\t\t{opacity: \"0.0\"}\n\t]);\n};\n\nexports.pop = PopStoryView;\n\n})();\n",
"type": "application/javascript",
"module-type": "storyview"
},
"$:/core/modules/storyviews/zoomin.js": {
"title": "$:/core/modules/storyviews/zoomin.js",
"text": "/*\\\ntitle: $:/core/modules/storyviews/zoomin.js\ntype: application/javascript\nmodule-type: storyview\n\nZooms between individual tiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar easing = \"cubic-bezier(0.645, 0.045, 0.355, 1)\"; // From http://easings.net/#easeInOutCubic\n\nvar ZoominListView = function(listWidget) {\n\tvar self = this;\n\tthis.listWidget = listWidget;\n\t// Get the index of the tiddler that is at the top of the history\n\tvar history = this.listWidget.wiki.getTiddlerDataCached(this.listWidget.historyTitle,[]),\n\t\ttargetTiddler;\n\tif(history.length > 0) {\n\t\ttargetTiddler = history[history.length-1].title;\n\t}\n\t// Make all the tiddlers position absolute, and hide all but the top (or first) one\n\t$tw.utils.each(this.listWidget.children,function(itemWidget,index) {\n\t\tvar domNode = itemWidget.findFirstDomNode();\n\t\t// Abandon if the list entry isn't a DOM element (it might be a text node)\n\t\tif(!(domNode instanceof Element)) {\n\t\t\treturn;\n\t\t}\n\t\tif((targetTiddler && targetTiddler !== itemWidget.parseTreeNode.itemTitle) || (!targetTiddler && index)) {\n\t\t\tdomNode.style.display = \"none\";\n\t\t} else {\n\t\t\tself.currentTiddlerDomNode = domNode;\n\t\t}\n\t\t$tw.utils.addClass(domNode,\"tc-storyview-zoomin-tiddler\");\n\t});\n};\n\nZoominListView.prototype.navigateTo = function(historyInfo) {\n\tvar duration = $tw.utils.getAnimationDuration(),\n\t\tlistElementIndex = this.listWidget.findListItem(0,historyInfo.title);\n\tif(listElementIndex === undefined) {\n\t\treturn;\n\t}\n\tvar listItemWidget = this.listWidget.children[listElementIndex],\n\t\ttargetElement = listItemWidget.findFirstDomNode();\n\t// Abandon if the list entry isn't a DOM element (it might be a text node)\n\tif(!(targetElement instanceof Element)) {\n\t\treturn;\n\t}\n\t// Make the new tiddler be position absolute and visible so that we can measure it\n\t$tw.utils.addClass(targetElement,\"tc-storyview-zoomin-tiddler\");\n\t$tw.utils.setStyle(targetElement,[\n\t\t{display: \"block\"},\n\t\t{transformOrigin: \"0 0\"},\n\t\t{transform: \"translateX(0px) translateY(0px) scale(1)\"},\n\t\t{transition: \"none\"},\n\t\t{opacity: \"0.0\"}\n\t]);\n\t// Get the position of the source node, or use the centre of the window as the source position\n\tvar sourceBounds = historyInfo.fromPageRect || {\n\t\t\tleft: window.innerWidth/2 - 2,\n\t\t\ttop: window.innerHeight/2 - 2,\n\t\t\twidth: window.innerWidth/8,\n\t\t\theight: window.innerHeight/8\n\t\t};\n\t// Try to find the title node in the target tiddler\n\tvar titleDomNode = findTitleDomNode(listItemWidget) || listItemWidget.findFirstDomNode(),\n\t\tzoomBounds = titleDomNode.getBoundingClientRect();\n\t// Compute the transform for the target tiddler to make the title lie over the source rectange\n\tvar targetBounds = targetElement.getBoundingClientRect(),\n\t\tscale = sourceBounds.width / zoomBounds.width,\n\t\tx = sourceBounds.left - targetBounds.left - (zoomBounds.left - targetBounds.left) * scale,\n\t\ty = sourceBounds.top - targetBounds.top - (zoomBounds.top - targetBounds.top) * scale;\n\t// Transform the target tiddler to its starting position\n\t$tw.utils.setStyle(targetElement,[\n\t\t{transform: \"translateX(\" + x + \"px) translateY(\" + y + \"px) scale(\" + scale + \")\"}\n\t]);\n\t// Force layout\n\t$tw.utils.forceLayout(targetElement);\n\t// Apply the ending transitions with a timeout to ensure that the previously applied transformations are applied first\n\tvar self = this,\n\t\tprevCurrentTiddler = this.currentTiddlerDomNode;\n\tthis.currentTiddlerDomNode = targetElement;\n\t// Transform the target tiddler to its natural size\n\t$tw.utils.setStyle(targetElement,[\n\t\t{transition: $tw.utils.roundTripPropertyName(\"transform\") + \" \" + duration + \"ms \" + easing + \", opacity \" + duration + \"ms \" + easing},\n\t\t{opacity: \"1.0\"},\n\t\t{transform: \"translateX(0px) translateY(0px) scale(1)\"},\n\t\t{zIndex: \"500\"},\n\t]);\n\t// Transform the previous tiddler out of the way and then hide it\n\tif(prevCurrentTiddler && prevCurrentTiddler !== targetElement) {\n\t\tscale = zoomBounds.width / sourceBounds.width;\n\t\tx = zoomBounds.left - targetBounds.left - (sourceBounds.left - targetBounds.left) * scale;\n\t\ty = zoomBounds.top - targetBounds.top - (sourceBounds.top - targetBounds.top) * scale;\n\t\t$tw.utils.setStyle(prevCurrentTiddler,[\n\t\t\t{transition: $tw.utils.roundTripPropertyName(\"transform\") + \" \" + duration + \"ms \" + easing + \", opacity \" + duration + \"ms \" + easing},\n\t\t\t{opacity: \"0.0\"},\n\t\t\t{transformOrigin: \"0 0\"},\n\t\t\t{transform: \"translateX(\" + x + \"px) translateY(\" + y + \"px) scale(\" + scale + \")\"},\n\t\t\t{zIndex: \"0\"}\n\t\t]);\n\t\t// Hide the tiddler when the transition has finished\n\t\tsetTimeout(function() {\n\t\t\tif(self.currentTiddlerDomNode !== prevCurrentTiddler) {\n\t\t\t\tprevCurrentTiddler.style.display = \"none\";\n\t\t\t}\n\t\t},duration);\n\t}\n\t// Scroll the target into view\n//\t$tw.pageScroller.scrollIntoView(targetElement);\n};\n\n/*\nFind the first child DOM node of a widget that has the class \"tc-title\"\n*/\nfunction findTitleDomNode(widget,targetClass) {\n\ttargetClass = targetClass || \"tc-title\";\n\tvar domNode = widget.findFirstDomNode();\n\tif(domNode && domNode.querySelector) {\n\t\treturn domNode.querySelector(\".\" + targetClass);\n\t}\n\treturn null;\n}\n\nZoominListView.prototype.insert = function(widget) {\n\tvar targetElement = widget.findFirstDomNode();\n\t// Abandon if the list entry isn't a DOM element (it might be a text node)\n\tif(!(targetElement instanceof Element)) {\n\t\treturn;\n\t}\n\t// Make the newly inserted node position absolute and hidden\n\t$tw.utils.addClass(targetElement,\"tc-storyview-zoomin-tiddler\");\n\t$tw.utils.setStyle(targetElement,[\n\t\t{display: \"none\"}\n\t]);\n};\n\nZoominListView.prototype.remove = function(widget) {\n\tvar targetElement = widget.findFirstDomNode(),\n\t\tduration = $tw.utils.getAnimationDuration(),\n\t\tremoveElement = function() {\n\t\t\twidget.removeChildDomNodes();\n\t\t};\n\t// Abandon if the list entry isn't a DOM element (it might be a text node)\n\tif(!(targetElement instanceof Element)) {\n\t\tremoveElement();\n\t\treturn;\n\t}\n\t// Abandon if hidden\n\tif(targetElement.style.display != \"block\" ) {\n\t\tremoveElement();\n\t\treturn;\n\t}\n\t// Set up the tiddler that is being closed\n\t$tw.utils.addClass(targetElement,\"tc-storyview-zoomin-tiddler\");\n\t$tw.utils.setStyle(targetElement,[\n\t\t{display: \"block\"},\n\t\t{transformOrigin: \"50% 50%\"},\n\t\t{transform: \"translateX(0px) translateY(0px) scale(1)\"},\n\t\t{transition: \"none\"},\n\t\t{zIndex: \"0\"}\n\t]);\n\t// We'll move back to the previous or next element in the story\n\tvar toWidget = widget.previousSibling();\n\tif(!toWidget) {\n\t\ttoWidget = widget.nextSibling();\n\t}\n\tvar toWidgetDomNode = toWidget && toWidget.findFirstDomNode();\n\t// Set up the tiddler we're moving back in\n\tif(toWidgetDomNode) {\n\t\t$tw.utils.addClass(toWidgetDomNode,\"tc-storyview-zoomin-tiddler\");\n\t\t$tw.utils.setStyle(toWidgetDomNode,[\n\t\t\t{display: \"block\"},\n\t\t\t{transformOrigin: \"50% 50%\"},\n\t\t\t{transform: \"translateX(0px) translateY(0px) scale(10)\"},\n\t\t\t{transition: $tw.utils.roundTripPropertyName(\"transform\") + \" \" + duration + \"ms \" + easing + \", opacity \" + duration + \"ms \" + easing},\n\t\t\t{opacity: \"0\"},\n\t\t\t{zIndex: \"500\"}\n\t\t]);\n\t\tthis.currentTiddlerDomNode = toWidgetDomNode;\n\t}\n\t// Animate them both\n\t// Force layout\n\t$tw.utils.forceLayout(this.listWidget.parentDomNode);\n\t// First, the tiddler we're closing\n\t$tw.utils.setStyle(targetElement,[\n\t\t{transformOrigin: \"50% 50%\"},\n\t\t{transform: \"translateX(0px) translateY(0px) scale(0.1)\"},\n\t\t{transition: $tw.utils.roundTripPropertyName(\"transform\") + \" \" + duration + \"ms \" + easing + \", opacity \" + duration + \"ms \" + easing},\n\t\t{opacity: \"0\"},\n\t\t{zIndex: \"0\"}\n\t]);\n\tsetTimeout(removeElement,duration);\n\t// Now the tiddler we're going back to\n\tif(toWidgetDomNode) {\n\t\t$tw.utils.setStyle(toWidgetDomNode,[\n\t\t\t{transform: \"translateX(0px) translateY(0px) scale(1)\"},\n\t\t\t{opacity: \"1\"}\n\t\t]);\n\t}\n\treturn true; // Indicate that we'll delete the DOM node\n};\n\nexports.zoomin = ZoominListView;\n\n})();\n",
"type": "application/javascript",
"module-type": "storyview"
},
"$:/core/modules/syncer.js": {
"title": "$:/core/modules/syncer.js",
"text": "/*\\\ntitle: $:/core/modules/syncer.js\ntype: application/javascript\nmodule-type: global\n\nThe syncer tracks changes to the store. If a syncadaptor is used then individual tiddlers are synchronised through it. If there is no syncadaptor then the entire wiki is saved via saver modules.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nDefaults\n*/\nSyncer.prototype.titleIsLoggedIn = \"$:/status/IsLoggedIn\";\nSyncer.prototype.titleIsAnonymous = \"$:/status/IsAnonymous\";\nSyncer.prototype.titleIsReadOnly = \"$:/status/IsReadOnly\";\nSyncer.prototype.titleUserName = \"$:/status/UserName\";\nSyncer.prototype.titleSyncFilter = \"$:/config/SyncFilter\";\nSyncer.prototype.titleSyncPollingInterval = \"$:/config/SyncPollingInterval\";\nSyncer.prototype.titleSavedNotification = \"$:/language/Notifications/Save/Done\";\nSyncer.prototype.taskTimerInterval = 1 * 1000; // Interval for sync timer\nSyncer.prototype.throttleInterval = 1 * 1000; // Defer saving tiddlers if they've changed in the last 1s...\nSyncer.prototype.fallbackInterval = 10 * 1000; // Unless the task is older than 10s\nSyncer.prototype.pollTimerInterval = 60 * 1000; // Interval for polling for changes from the adaptor\n\n/*\nInstantiate the syncer with the following options:\nsyncadaptor: reference to syncadaptor to be used\nwiki: wiki to be synced\n*/\nfunction Syncer(options) {\n\tvar self = this;\n\tthis.wiki = options.wiki;\n\tthis.syncadaptor = options.syncadaptor;\n\tthis.disableUI = !!options.disableUI;\n\tthis.titleIsLoggedIn = options.titleIsLoggedIn || this.titleIsLoggedIn;\n\tthis.titleUserName = options.titleUserName || this.titleUserName;\n\tthis.titleSyncFilter = options.titleSyncFilter || this.titleSyncFilter;\n\tthis.titleSavedNotification = options.titleSavedNotification || this.titleSavedNotification;\n\tthis.taskTimerInterval = options.taskTimerInterval || this.taskTimerInterval;\n\tthis.throttleInterval = options.throttleInterval || this.throttleInterval;\n\tthis.fallbackInterval = options.fallbackInterval || this.fallbackInterval;\n\tthis.pollTimerInterval = options.pollTimerInterval || parseInt(this.wiki.getTiddlerText(this.titleSyncPollingInterval,\"\"),10) || this.pollTimerInterval;\n\tthis.logging = \"logging\" in options ? options.logging : true;\n\t// Make a logger\n\tthis.logger = new $tw.utils.Logger(\"syncer\" + ($tw.browser ? \"-browser\" : \"\") + ($tw.node ? \"-server\" : \"\") + (this.syncadaptor.name ? (\"-\" + this.syncadaptor.name) : \"\"),{\n\t\t\tcolour: \"cyan\",\n\t\t\tenable: this.logging\n\t\t});\n\t// Compile the dirty tiddler filter\n\tthis.filterFn = this.wiki.compileFilter(this.wiki.getTiddlerText(this.titleSyncFilter));\n\t// Record information for known tiddlers\n\tthis.readTiddlerInfo();\n\t// Tasks are {type: \"load\"/\"save\"/\"delete\", title:, queueTime:, lastModificationTime:}\n\tthis.taskQueue = {}; // Hashmap of tasks yet to be performed\n\tthis.taskInProgress = {}; // Hash of tasks in progress\n\tthis.taskTimerId = null; // Timer for task dispatch\n\tthis.pollTimerId = null; // Timer for polling server\n\t// Listen out for changes to tiddlers\n\tthis.wiki.addEventListener(\"change\",function(changes) {\n\t\tself.syncToServer(changes);\n\t});\n\t// Browser event handlers\n\tif($tw.browser && !this.disableUI) {\n\t\t// Set up our beforeunload handler\n\t\t$tw.addUnloadTask(function(event) {\n\t\t\tvar confirmationMessage;\n\t\t\tif(self.isDirty()) {\n\t\t\t\tconfirmationMessage = $tw.language.getString(\"UnsavedChangesWarning\");\n\t\t\t\tevent.returnValue = confirmationMessage; // Gecko\n\t\t\t}\n\t\t\treturn confirmationMessage;\n\t\t});\n\t\t// Listen out for login/logout/refresh events in the browser\n\t\t$tw.rootWidget.addEventListener(\"tm-login\",function() {\n\t\t\tself.handleLoginEvent();\n\t\t});\n\t\t$tw.rootWidget.addEventListener(\"tm-logout\",function() {\n\t\t\tself.handleLogoutEvent();\n\t\t});\n\t\t$tw.rootWidget.addEventListener(\"tm-server-refresh\",function() {\n\t\t\tself.handleRefreshEvent();\n\t\t});\n\t}\n\t// Listen out for lazyLoad events\n\tif(!this.disableUI) {\n\t\tthis.wiki.addEventListener(\"lazyLoad\",function(title) {\n\t\t\tself.handleLazyLoadEvent(title);\n\t\t});\t\t\n\t}\n\t// Get the login status\n\tthis.getStatus(function(err,isLoggedIn) {\n\t\t// Do a sync from the server\n\t\tself.syncFromServer();\n\t});\n}\n\n/*\nRead (or re-read) the latest tiddler info from the store\n*/\nSyncer.prototype.readTiddlerInfo = function() {\n\t// Hashmap by title of {revision:,changeCount:,adaptorInfo:}\n\tthis.tiddlerInfo = {};\n\t// Record information for known tiddlers\n\tvar self = this,\n\t\ttiddlers = this.filterFn.call(this.wiki);\n\t$tw.utils.each(tiddlers,function(title) {\n\t\tvar tiddler = self.wiki.getTiddler(title);\n\t\tself.tiddlerInfo[title] = {\n\t\t\trevision: tiddler.fields.revision,\n\t\t\tadaptorInfo: self.syncadaptor && self.syncadaptor.getTiddlerInfo(tiddler),\n\t\t\tchangeCount: self.wiki.getChangeCount(title),\n\t\t\thasBeenLazyLoaded: false\n\t\t};\n\t});\n};\n\n/*\nCreate an tiddlerInfo structure if it doesn't already exist\n*/\nSyncer.prototype.createTiddlerInfo = function(title) {\n\tif(!$tw.utils.hop(this.tiddlerInfo,title)) {\n\t\tthis.tiddlerInfo[title] = {\n\t\t\trevision: null,\n\t\t\tadaptorInfo: {},\n\t\t\tchangeCount: -1,\n\t\t\thasBeenLazyLoaded: false\n\t\t};\n\t}\n};\n\n/*\nChecks whether the wiki is dirty (ie the window shouldn't be closed)\n*/\nSyncer.prototype.isDirty = function() {\n\treturn (this.numTasksInQueue() > 0) || (this.numTasksInProgress() > 0);\n};\n\n/*\nUpdate the document body with the class \"tc-dirty\" if the wiki has unsaved/unsynced changes\n*/\nSyncer.prototype.updateDirtyStatus = function() {\n\tif($tw.browser && !this.disableUI) {\n\t\t$tw.utils.toggleClass(document.body,\"tc-dirty\",this.isDirty());\n\t}\n};\n\n/*\nSave an incoming tiddler in the store, and updates the associated tiddlerInfo\n*/\nSyncer.prototype.storeTiddler = function(tiddlerFields,hasBeenLazyLoaded) {\n\t// Save the tiddler\n\tvar tiddler = new $tw.Tiddler(tiddlerFields);\n\tthis.wiki.addTiddler(tiddler);\n\t// Save the tiddler revision and changeCount details\n\tthis.tiddlerInfo[tiddlerFields.title] = {\n\t\trevision: tiddlerFields.revision,\n\t\tadaptorInfo: this.syncadaptor.getTiddlerInfo(tiddler),\n\t\tchangeCount: this.wiki.getChangeCount(tiddlerFields.title),\n\t\thasBeenLazyLoaded: hasBeenLazyLoaded !== undefined ? hasBeenLazyLoaded : true\n\t};\n};\n\nSyncer.prototype.getStatus = function(callback) {\n\tvar self = this;\n\t// Check if the adaptor supports getStatus()\n\tif(this.syncadaptor && this.syncadaptor.getStatus) {\n\t\t// Mark us as not logged in\n\t\tthis.wiki.addTiddler({title: this.titleIsLoggedIn,text: \"no\"});\n\t\t// Get login status\n\t\tthis.syncadaptor.getStatus(function(err,isLoggedIn,username,isReadOnly,isAnonymous) {\n\t\t\tif(err) {\n\t\t\t\tself.logger.alert(err);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Set the various status tiddlers\n\t\t\tself.wiki.addTiddler({title: self.titleIsReadOnly,text: isReadOnly ? \"yes\" : \"no\"});\n\t\t\tself.wiki.addTiddler({title: self.titleIsAnonymous,text: isAnonymous ? \"yes\" : \"no\"});\n\t\t\tself.wiki.addTiddler({title: self.titleIsLoggedIn,text: isLoggedIn ? \"yes\" : \"no\"});\n\t\t\tif(isLoggedIn) {\n\t\t\t\tself.wiki.addTiddler({title: self.titleUserName,text: username || \"\"});\n\t\t\t}\n\t\t\t// Invoke the callback\n\t\t\tif(callback) {\n\t\t\t\tcallback(err,isLoggedIn,username);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tcallback(null,true,\"UNAUTHENTICATED\");\n\t}\n};\n\n/*\nSynchronise from the server by reading the skinny tiddler list and queuing up loads for any tiddlers that we don't already have up to date\n*/\nSyncer.prototype.syncFromServer = function() {\n\tif(this.syncadaptor && this.syncadaptor.getSkinnyTiddlers) {\n\t\tthis.logger.log(\"Retrieving skinny tiddler list\");\n\t\tvar self = this;\n\t\tif(this.pollTimerId) {\n\t\t\tclearTimeout(this.pollTimerId);\n\t\t\tthis.pollTimerId = null;\n\t\t}\n\t\tthis.syncadaptor.getSkinnyTiddlers(function(err,tiddlers) {\n\t\t\t// Trigger the next sync\n\t\t\tself.pollTimerId = setTimeout(function() {\n\t\t\t\tself.pollTimerId = null;\n\t\t\t\tself.syncFromServer.call(self);\n\t\t\t},self.pollTimerInterval);\n\t\t\t// Check for errors\n\t\t\tif(err) {\n\t\t\t\tself.logger.alert($tw.language.getString(\"Error/RetrievingSkinny\") + \":\",err);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Process each incoming tiddler\n\t\t\tfor(var t=0; t<tiddlers.length; t++) {\n\t\t\t\t// Get the incoming tiddler fields, and the existing tiddler\n\t\t\t\tvar tiddlerFields = tiddlers[t],\n\t\t\t\t\tincomingRevision = tiddlerFields.revision + \"\",\n\t\t\t\t\ttiddler = self.wiki.getTiddler(tiddlerFields.title),\n\t\t\t\t\ttiddlerInfo = self.tiddlerInfo[tiddlerFields.title],\n\t\t\t\t\tcurrRevision = tiddlerInfo ? tiddlerInfo.revision : null;\n\t\t\t\t// Ignore the incoming tiddler if it's the same as the revision we've already got\n\t\t\t\tif(currRevision !== incomingRevision) {\n\t\t\t\t\t// Do a full load if we've already got a fat version of the tiddler\n\t\t\t\t\tif(tiddler && tiddler.fields.text !== undefined) {\n\t\t\t\t\t\t// Do a full load of this tiddler\n\t\t\t\t\t\tself.enqueueSyncTask({\n\t\t\t\t\t\t\ttype: \"load\",\n\t\t\t\t\t\t\ttitle: tiddlerFields.title\n\t\t\t\t\t\t});\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Load the skinny version of the tiddler\n\t\t\t\t\t\tself.storeTiddler(tiddlerFields,false);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n};\n\n/*\nSynchronise a set of changes to the server\n*/\nSyncer.prototype.syncToServer = function(changes) {\n\tvar self = this,\n\t\tnow = Date.now(),\n\t\tfilteredChanges = this.filterFn.call(this.wiki,function(callback) {\n\t\t\t$tw.utils.each(changes,function(change,title) {\n\t\t\t\tvar tiddler = self.wiki.getTiddler(title);\n\t\t\t\tcallback(tiddler,title);\n\t\t\t});\n\t\t});\n\t$tw.utils.each(changes,function(change,title,object) {\n\t\t// Process the change if it is a deletion of a tiddler we're already syncing, or is on the filtered change list\n\t\tif((change.deleted && $tw.utils.hop(self.tiddlerInfo,title)) || filteredChanges.indexOf(title) !== -1) {\n\t\t\t// Queue a task to sync this tiddler\n\t\t\tself.enqueueSyncTask({\n\t\t\t\ttype: change.deleted ? \"delete\" : \"save\",\n\t\t\t\ttitle: title\n\t\t\t});\n\t\t}\n\t});\n};\n\n/*\nLazily load a skinny tiddler if we can\n*/\nSyncer.prototype.handleLazyLoadEvent = function(title) {\n\t// Don't lazy load the same tiddler twice\n\tvar info = this.tiddlerInfo[title];\n\tif(!info || !info.hasBeenLazyLoaded) {\n\t\t// Don't lazy load if the tiddler isn't included in the sync filter\n\t\tif(this.filterFn.call(this.wiki).indexOf(title) !== -1) {\n\t\t\tthis.createTiddlerInfo(title);\n\t\t\tthis.tiddlerInfo[title].hasBeenLazyLoaded = true;\n\t\t\t// Queue up a sync task to load this tiddler\n\t\t\tthis.enqueueSyncTask({\n\t\t\t\ttype: \"load\",\n\t\t\t\ttitle: title\n\t\t\t});\n\t\t}\n\t}\n};\n\n/*\nDispay a password prompt and allow the user to login\n*/\nSyncer.prototype.handleLoginEvent = function() {\n\tvar self = this;\n\tthis.getStatus(function(err,isLoggedIn,username) {\n\t\tif(!isLoggedIn) {\n\t\t\t$tw.passwordPrompt.createPrompt({\n\t\t\t\tserviceName: $tw.language.getString(\"LoginToTiddlySpace\"),\n\t\t\t\tcallback: function(data) {\n\t\t\t\t\tself.login(data.username,data.password,function(err,isLoggedIn) {\n\t\t\t\t\t\tself.syncFromServer();\n\t\t\t\t\t});\n\t\t\t\t\treturn true; // Get rid of the password prompt\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t});\n};\n\n/*\nAttempt to login to TiddlyWeb.\n\tusername: username\n\tpassword: password\n\tcallback: invoked with arguments (err,isLoggedIn)\n*/\nSyncer.prototype.login = function(username,password,callback) {\n\tthis.logger.log(\"Attempting to login as\",username);\n\tvar self = this;\n\tif(this.syncadaptor.login) {\n\t\tthis.syncadaptor.login(username,password,function(err) {\n\t\t\tif(err) {\n\t\t\t\treturn callback(err);\n\t\t\t}\n\t\t\tself.getStatus(function(err,isLoggedIn,username) {\n\t\t\t\tif(callback) {\n\t\t\t\t\tcallback(null,isLoggedIn);\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t} else {\n\t\tcallback(null,true);\n\t}\n};\n\n/*\nAttempt to log out of TiddlyWeb\n*/\nSyncer.prototype.handleLogoutEvent = function() {\n\tthis.logger.log(\"Attempting to logout\");\n\tvar self = this;\n\tif(this.syncadaptor.logout) {\n\t\tthis.syncadaptor.logout(function(err) {\n\t\t\tif(err) {\n\t\t\t\tself.logger.alert(err);\n\t\t\t} else {\n\t\t\t\tself.getStatus();\n\t\t\t}\n\t\t});\n\t}\n};\n\n/*\nImmediately refresh from the server\n*/\nSyncer.prototype.handleRefreshEvent = function() {\n\tthis.syncFromServer();\n};\n\n/*\nQueue up a sync task. If there is already a pending task for the tiddler, just update the last modification time\n*/\nSyncer.prototype.enqueueSyncTask = function(task) {\n\tvar self = this,\n\t\tnow = Date.now();\n\t// Set the timestamps on this task\n\ttask.queueTime = now;\n\ttask.lastModificationTime = now;\n\t// Fill in some tiddlerInfo if the tiddler is one we haven't seen before\n\tthis.createTiddlerInfo(task.title);\n\t// Bail if this is a save and the tiddler is already at the changeCount that the server has\n\tif(task.type === \"save\" && this.wiki.getChangeCount(task.title) <= this.tiddlerInfo[task.title].changeCount) {\n\t\treturn;\n\t}\n\t// Check if this tiddler is already in the queue\n\tif($tw.utils.hop(this.taskQueue,task.title)) {\n\t\t// this.logger.log(\"Re-queueing up sync task with type:\",task.type,\"title:\",task.title);\n\t\tvar existingTask = this.taskQueue[task.title];\n\t\t// If so, just update the last modification time\n\t\texistingTask.lastModificationTime = task.lastModificationTime;\n\t\t// If the new task is a save then we upgrade the existing task to a save. Thus a pending load is turned into a save if the tiddler changes locally in the meantime. But a pending save is not modified to become a load\n\t\tif(task.type === \"save\" || task.type === \"delete\") {\n\t\t\texistingTask.type = task.type;\n\t\t}\n\t} else {\n\t\t// this.logger.log(\"Queuing up sync task with type:\",task.type,\"title:\",task.title);\n\t\t// If it is not in the queue, insert it\n\t\tthis.taskQueue[task.title] = task;\n\t\tthis.updateDirtyStatus();\n\t}\n\t// Process the queue\n\t$tw.utils.nextTick(function() {self.processTaskQueue.call(self);});\n};\n\n/*\nReturn the number of tasks in progress\n*/\nSyncer.prototype.numTasksInProgress = function() {\n\treturn $tw.utils.count(this.taskInProgress);\n};\n\n/*\nReturn the number of tasks in the queue\n*/\nSyncer.prototype.numTasksInQueue = function() {\n\treturn $tw.utils.count(this.taskQueue);\n};\n\n/*\nTrigger a timeout if one isn't already outstanding\n*/\nSyncer.prototype.triggerTimeout = function() {\n\tvar self = this;\n\tif(!this.taskTimerId) {\n\t\tthis.taskTimerId = setTimeout(function() {\n\t\t\tself.taskTimerId = null;\n\t\t\tself.processTaskQueue.call(self);\n\t\t},self.taskTimerInterval);\n\t}\n};\n\n/*\nProcess the task queue, performing the next task if appropriate\n*/\nSyncer.prototype.processTaskQueue = function() {\n\tvar self = this;\n\t// Only process a task if the sync adaptor is fully initialised and we're not already performing a task. If we are already performing a task then we'll dispatch the next one when it completes\n\tif((!this.syncadaptor.isReady || this.syncadaptor.isReady()) && this.numTasksInProgress() === 0) {\n\t\t// Choose the next task to perform\n\t\tvar task = this.chooseNextTask();\n\t\t// Perform the task if we had one\n\t\tif(task) {\n\t\t\t// Remove the task from the queue and add it to the in progress list\n\t\t\tdelete this.taskQueue[task.title];\n\t\t\tthis.taskInProgress[task.title] = task;\n\t\t\tthis.updateDirtyStatus();\n\t\t\t// Dispatch the task\n\t\t\tthis.dispatchTask(task,function(err) {\n\t\t\t\tif(err) {\n\t\t\t\t\tself.logger.alert(\"Sync error while processing '\" + task.title + \"':\\n\" + err);\n\t\t\t\t}\n\t\t\t\t// Mark that this task is no longer in progress\n\t\t\t\tdelete self.taskInProgress[task.title];\n\t\t\t\tself.updateDirtyStatus();\n\t\t\t\t// Process the next task\n\t\t\t\tself.processTaskQueue.call(self);\n\t\t\t});\n\t\t} else {\n\t\t\t// Make sure we've set a time if there wasn't a task to perform, but we've still got tasks in the queue\n\t\t\tif(this.numTasksInQueue() > 0) {\n\t\t\t\tthis.triggerTimeout();\n\t\t\t}\n\t\t}\n\t}\n};\n\n/*\nChoose the next applicable task\n*/\nSyncer.prototype.chooseNextTask = function() {\n\tvar self = this,\n\t\tcandidateTask = null,\n\t\tnow = Date.now();\n\t// Select the best candidate task\n\t$tw.utils.each(this.taskQueue,function(task,title) {\n\t\t// Exclude the task if there's one of the same name in progress\n\t\tif($tw.utils.hop(self.taskInProgress,title)) {\n\t\t\treturn;\n\t\t}\n\t\t// Exclude the task if it is a save and the tiddler has been modified recently, but not hit the fallback time\n\t\tif(task.type === \"save\" && (now - task.lastModificationTime) < self.throttleInterval &&\n\t\t\t(now - task.queueTime) < self.fallbackInterval) {\n\t\t\treturn;\n\t\t}\n\t\t// Exclude the task if it is newer than the current best candidate\n\t\tif(candidateTask && candidateTask.queueTime < task.queueTime) {\n\t\t\treturn;\n\t\t}\n\t\t// Now this is our best candidate\n\t\tcandidateTask = task;\n\t});\n\treturn candidateTask;\n};\n\n/*\nDispatch a task and invoke the callback\n*/\nSyncer.prototype.dispatchTask = function(task,callback) {\n\tvar self = this;\n\tif(task.type === \"save\") {\n\t\tvar changeCount = this.wiki.getChangeCount(task.title),\n\t\t\ttiddler = this.wiki.getTiddler(task.title);\n\t\tthis.logger.log(\"Dispatching 'save' task:\",task.title);\n\t\tif(tiddler) {\n\t\t\tthis.syncadaptor.saveTiddler(tiddler,function(err,adaptorInfo,revision) {\n\t\t\t\tif(err) {\n\t\t\t\t\treturn callback(err);\n\t\t\t\t}\n\t\t\t\t// Adjust the info stored about this tiddler\n\t\t\t\tself.tiddlerInfo[task.title] = {\n\t\t\t\t\tchangeCount: changeCount,\n\t\t\t\t\tadaptorInfo: adaptorInfo,\n\t\t\t\t\trevision: revision\n\t\t\t\t};\n\t\t\t\t// Invoke the callback\n\t\t\t\tcallback(null);\n\t\t\t},{\n\t\t\t\ttiddlerInfo: self.tiddlerInfo[task.title]\n\t\t\t});\n\t\t} else {\n\t\t\tthis.logger.log(\" Not Dispatching 'save' task:\",task.title,\"tiddler does not exist\");\n\t\t\treturn callback(null);\n\t\t}\n\t} else if(task.type === \"load\") {\n\t\t// Load the tiddler\n\t\tthis.logger.log(\"Dispatching 'load' task:\",task.title);\n\t\tthis.syncadaptor.loadTiddler(task.title,function(err,tiddlerFields) {\n\t\t\tif(err) {\n\t\t\t\treturn callback(err);\n\t\t\t}\n\t\t\t// Store the tiddler\n\t\t\tif(tiddlerFields) {\n\t\t\t\tself.storeTiddler(tiddlerFields,true);\n\t\t\t}\n\t\t\t// Invoke the callback\n\t\t\tcallback(null);\n\t\t});\n\t} else if(task.type === \"delete\") {\n\t\t// Delete the tiddler\n\t\tthis.logger.log(\"Dispatching 'delete' task:\",task.title);\n\t\tthis.syncadaptor.deleteTiddler(task.title,function(err) {\n\t\t\tif(err) {\n\t\t\t\treturn callback(err);\n\t\t\t}\n\t\t\tdelete self.tiddlerInfo[task.title];\n\t\t\t// Invoke the callback\n\t\t\tcallback(null);\n\t\t},{\n\t\t\ttiddlerInfo: self.tiddlerInfo[task.title]\n\t\t});\n\t}\n};\n\nexports.Syncer = Syncer;\n\n})();\n",
"type": "application/javascript",
"module-type": "global"
},
"$:/core/modules/tiddler.js": {
"title": "$:/core/modules/tiddler.js",
"text": "/*\\\ntitle: $:/core/modules/tiddler.js\ntype: application/javascript\nmodule-type: tiddlermethod\n\nExtension methods for the $tw.Tiddler object (constructor and methods required at boot time are in boot/boot.js)\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.hasTag = function(tag) {\n\treturn this.fields.tags && this.fields.tags.indexOf(tag) !== -1;\n};\n\nexports.isPlugin = function() {\n\treturn this.fields.type === \"application/json\" && this.hasField(\"plugin-type\");\n};\n\nexports.isDraft = function() {\n\treturn this.hasField(\"draft.of\");\n};\n\nexports.getFieldString = function(field) {\n\tvar value = this.fields[field];\n\t// Check for a missing field\n\tif(value === undefined || value === null) {\n\t\treturn \"\";\n\t}\n\t// Parse the field with the associated module (if any)\n\tvar fieldModule = $tw.Tiddler.fieldModules[field];\n\tif(fieldModule && fieldModule.stringify) {\n\t\treturn fieldModule.stringify.call(this,value);\n\t} else {\n\t\treturn value.toString();\n\t}\n};\n\n/*\nGet the value of a field as a list\n*/\nexports.getFieldList = function(field) {\n\tvar value = this.fields[field];\n\t// Check for a missing field\n\tif(value === undefined || value === null) {\n\t\treturn [];\n\t}\n\treturn $tw.utils.parseStringArray(value);\n};\n\n/*\nGet all the fields as a hashmap of strings. Options:\n\texclude: an array of field names to exclude\n*/\nexports.getFieldStrings = function(options) {\n\toptions = options || {};\n\tvar exclude = options.exclude || [];\n\tvar fields = {};\n\tfor(var field in this.fields) {\n\t\tif($tw.utils.hop(this.fields,field)) {\n\t\t\tif(exclude.indexOf(field) === -1) {\n\t\t\t\tfields[field] = this.getFieldString(field);\n\t\t\t}\n\t\t}\n\t}\n\treturn fields;\n};\n\n/*\nGet all the fields as a name:value block. Options:\n\texclude: an array of field names to exclude\n*/\nexports.getFieldStringBlock = function(options) {\n\toptions = options || {};\n\tvar exclude = options.exclude || [];\n\tvar fields = [];\n\tfor(var field in this.fields) {\n\t\tif($tw.utils.hop(this.fields,field)) {\n\t\t\tif(exclude.indexOf(field) === -1) {\n\t\t\t\tfields.push(field + \": \" + this.getFieldString(field));\n\t\t\t}\n\t\t}\n\t}\n\treturn fields.join(\"\\n\");\n};\n\n/*\nCompare two tiddlers for equality\ntiddler: the tiddler to compare\nexcludeFields: array of field names to exclude from the comparison\n*/\nexports.isEqual = function(tiddler,excludeFields) {\n\tif(!(tiddler instanceof $tw.Tiddler)) {\n\t\treturn false;\n\t}\n\texcludeFields = excludeFields || [];\n\tvar self = this,\n\t\tdifferences = []; // Fields that have differences\n\t// Add to the differences array\n\tfunction addDifference(fieldName) {\n\t\t// Check for this field being excluded\n\t\tif(excludeFields.indexOf(fieldName) === -1) {\n\t\t\t// Save the field as a difference\n\t\t\t$tw.utils.pushTop(differences,fieldName);\n\t\t}\n\t}\n\t// Returns true if the two values of this field are equal\n\tfunction isFieldValueEqual(fieldName) {\n\t\tvar valueA = self.fields[fieldName],\n\t\t\tvalueB = tiddler.fields[fieldName];\n\t\t// Check for identical string values\n\t\tif(typeof(valueA) === \"string\" && typeof(valueB) === \"string\" && valueA === valueB) {\n\t\t\treturn true;\n\t\t}\n\t\t// Check for identical array values\n\t\tif($tw.utils.isArray(valueA) && $tw.utils.isArray(valueB) && $tw.utils.isArrayEqual(valueA,valueB)) {\n\t\t\treturn true;\n\t\t}\n\t\t// Otherwise the fields must be different\n\t\treturn false;\n\t}\n\t// Compare our fields\n\tfor(var fieldName in this.fields) {\n\t\tif(!isFieldValueEqual(fieldName)) {\n\t\t\taddDifference(fieldName);\n\t\t}\n\t}\n\t// There's a difference for every field in the other tiddler that we don't have\n\tfor(fieldName in tiddler.fields) {\n\t\tif(!(fieldName in this.fields)) {\n\t\t\taddDifference(fieldName);\n\t\t}\n\t}\n\t// Return whether there were any differences\n\treturn differences.length === 0;\n};\n\nexports.getFieldDay = function(field) {\n\tif(this.cache && this.cache.day && $tw.utils.hop(this.cache.day,field) ) {\n\t\treturn this.cache.day[field];\n\t}\n\tvar day = \"\";\n\tif(this.fields[field]) {\n\t\tday = (new Date($tw.utils.parseDate(this.fields[field]))).setHours(0,0,0,0);\n\t}\n\tthis.cache.day = this.cache.day || {};\n\tthis.cache.day[field] = day;\n\treturn day;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "tiddlermethod"
},
"$:/core/modules/upgraders/plugins.js": {
"title": "$:/core/modules/upgraders/plugins.js",
"text": "/*\\\ntitle: $:/core/modules/upgraders/plugins.js\ntype: application/javascript\nmodule-type: upgrader\n\nUpgrader module that checks that plugins are newer than any already installed version\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar UPGRADE_LIBRARY_TITLE = \"$:/UpgradeLibrary\";\n\nvar BLOCKED_PLUGINS = {\n\t\"$:/themes/tiddlywiki/stickytitles\": {\n\t\tversions: [\"*\"]\n\t},\n\t\"$:/plugins/tiddlywiki/fullscreen\": {\n\t\tversions: [\"*\"]\n\t}\n};\n\nexports.upgrade = function(wiki,titles,tiddlers) {\n\tvar self = this,\n\t\tmessages = {},\n\t\tupgradeLibrary,\n\t\tgetLibraryTiddler = function(title) {\n\t\t\tif(!upgradeLibrary) {\n\t\t\t\tupgradeLibrary = wiki.getTiddlerData(UPGRADE_LIBRARY_TITLE,{});\n\t\t\t\tupgradeLibrary.tiddlers = upgradeLibrary.tiddlers || {};\n\t\t\t}\n\t\t\treturn upgradeLibrary.tiddlers[title];\n\t\t};\n\n\t// Go through all the incoming tiddlers\n\t$tw.utils.each(titles,function(title) {\n\t\tvar incomingTiddler = tiddlers[title];\n\t\t// Check if we're dealing with a plugin\n\t\tif(incomingTiddler && incomingTiddler[\"plugin-type\"] && incomingTiddler.version) {\n\t\t\t// Upgrade the incoming plugin if it is in the upgrade library\n\t\t\tvar libraryTiddler = getLibraryTiddler(title);\n\t\t\tif(libraryTiddler && libraryTiddler[\"plugin-type\"] && libraryTiddler.version) {\n\t\t\t\ttiddlers[title] = libraryTiddler;\n\t\t\t\tmessages[title] = $tw.language.getString(\"Import/Upgrader/Plugins/Upgraded\",{variables: {incoming: incomingTiddler.version, upgraded: libraryTiddler.version}});\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Suppress the incoming plugin if it is older than the currently installed one\n\t\t\tvar existingTiddler = wiki.getTiddler(title);\n\t\t\tif(existingTiddler && existingTiddler.hasField(\"plugin-type\") && existingTiddler.hasField(\"version\")) {\n\t\t\t\t// Reject the incoming plugin by blanking all its fields\n\t\t\t\tif($tw.utils.checkVersions(existingTiddler.fields.version,incomingTiddler.version)) {\n\t\t\t\t\ttiddlers[title] = Object.create(null);\n\t\t\t\t\tmessages[title] = $tw.language.getString(\"Import/Upgrader/Plugins/Suppressed/Version\",{variables: {incoming: incomingTiddler.version, existing: existingTiddler.fields.version}});\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif(incomingTiddler && incomingTiddler[\"plugin-type\"]) {\n\t\t\t// Check whether the plugin is on the blocked list\n\t\t\tvar blockInfo = BLOCKED_PLUGINS[title];\n\t\t\tif(blockInfo) {\n\t\t\t\tif(blockInfo.versions.indexOf(\"*\") !== -1 || (incomingTiddler.version && blockInfo.versions.indexOf(incomingTiddler.version) !== -1)) {\n\t\t\t\t\ttiddlers[title] = Object.create(null);\n\t\t\t\t\tmessages[title] = $tw.language.getString(\"Import/Upgrader/Plugins/Suppressed/Incompatible\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n\treturn messages;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "upgrader"
},
"$:/core/modules/upgraders/system.js": {
"title": "$:/core/modules/upgraders/system.js",
"text": "/*\\\ntitle: $:/core/modules/upgraders/system.js\ntype: application/javascript\nmodule-type: upgrader\n\nUpgrader module that suppresses certain system tiddlers that shouldn't be imported\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar DONT_IMPORT_LIST = [\"$:/StoryList\",\"$:/HistoryList\"],\n\tDONT_IMPORT_PREFIX_LIST = [\"$:/temp/\",\"$:/state/\"];\n\nexports.upgrade = function(wiki,titles,tiddlers) {\n\tvar self = this,\n\t\tmessages = {};\n\t// Check for tiddlers on our list\n\t$tw.utils.each(titles,function(title) {\n\t\tif(DONT_IMPORT_LIST.indexOf(title) !== -1) {\n\t\t\ttiddlers[title] = Object.create(null);\n\t\t\tmessages[title] = $tw.language.getString(\"Import/Upgrader/System/Suppressed\");\n\t\t} else {\n\t\t\tfor(var t=0; t<DONT_IMPORT_PREFIX_LIST.length; t++) {\n\t\t\t\tvar prefix = DONT_IMPORT_PREFIX_LIST[t];\n\t\t\t\tif(title.substr(0,prefix.length) === prefix) {\n\t\t\t\t\ttiddlers[title] = Object.create(null);\n\t\t\t\t\tmessages[title] = $tw.language.getString(\"Import/Upgrader/State/Suppressed\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n\treturn messages;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "upgrader"
},
"$:/core/modules/upgraders/themetweaks.js": {
"title": "$:/core/modules/upgraders/themetweaks.js",
"text": "/*\\\ntitle: $:/core/modules/upgraders/themetweaks.js\ntype: application/javascript\nmodule-type: upgrader\n\nUpgrader module that handles the change in theme tweak storage introduced in 5.0.14-beta.\n\nPreviously, theme tweaks were stored in two data tiddlers:\n\n* $:/themes/tiddlywiki/vanilla/metrics\n* $:/themes/tiddlywiki/vanilla/settings\n\nNow, each tweak is stored in its own separate tiddler.\n\nThis upgrader copies any values from the old format to the new. The old data tiddlers are not deleted in case they have been used to store additional indexes.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar MAPPINGS = {\n\t\"$:/themes/tiddlywiki/vanilla/metrics\": {\n\t\t\"fontsize\": \"$:/themes/tiddlywiki/vanilla/metrics/fontsize\",\n\t\t\"lineheight\": \"$:/themes/tiddlywiki/vanilla/metrics/lineheight\",\n\t\t\"storyleft\": \"$:/themes/tiddlywiki/vanilla/metrics/storyleft\",\n\t\t\"storytop\": \"$:/themes/tiddlywiki/vanilla/metrics/storytop\",\n\t\t\"storyright\": \"$:/themes/tiddlywiki/vanilla/metrics/storyright\",\n\t\t\"storywidth\": \"$:/themes/tiddlywiki/vanilla/metrics/storywidth\",\n\t\t\"tiddlerwidth\": \"$:/themes/tiddlywiki/vanilla/metrics/tiddlerwidth\"\n\t},\n\t\"$:/themes/tiddlywiki/vanilla/settings\": {\n\t\t\"fontfamily\": \"$:/themes/tiddlywiki/vanilla/settings/fontfamily\"\n\t}\n};\n\nexports.upgrade = function(wiki,titles,tiddlers) {\n\tvar self = this,\n\t\tmessages = {};\n\t// Check for tiddlers on our list\n\t$tw.utils.each(titles,function(title) {\n\t\tvar mapping = MAPPINGS[title];\n\t\tif(mapping) {\n\t\t\tvar tiddler = new $tw.Tiddler(tiddlers[title]),\n\t\t\t\ttiddlerData = wiki.getTiddlerDataCached(tiddler,{});\n\t\t\tfor(var index in mapping) {\n\t\t\t\tvar mappedTitle = mapping[index];\n\t\t\t\tif(!tiddlers[mappedTitle] || tiddlers[mappedTitle].title !== mappedTitle) {\n\t\t\t\t\ttiddlers[mappedTitle] = {\n\t\t\t\t\t\ttitle: mappedTitle,\n\t\t\t\t\t\ttext: tiddlerData[index]\n\t\t\t\t\t};\n\t\t\t\t\tmessages[mappedTitle] = $tw.language.getString(\"Import/Upgrader/ThemeTweaks/Created\",{variables: {\n\t\t\t\t\t\tfrom: title + \"##\" + index\n\t\t\t\t\t}});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n\treturn messages;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "upgrader"
},
"$:/core/modules/utils/crypto.js": {
"title": "$:/core/modules/utils/crypto.js",
"text": "/*\\\ntitle: $:/core/modules/utils/crypto.js\ntype: application/javascript\nmodule-type: utils\n\nUtility functions related to crypto.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nLook for an encrypted store area in the text of a TiddlyWiki file\n*/\nexports.extractEncryptedStoreArea = function(text) {\n\tvar encryptedStoreAreaStartMarker = \"<pre id=\\\"encryptedStoreArea\\\" type=\\\"text/plain\\\" style=\\\"display:none;\\\">\",\n\t\tencryptedStoreAreaStart = text.indexOf(encryptedStoreAreaStartMarker);\n\tif(encryptedStoreAreaStart !== -1) {\n\t\tvar encryptedStoreAreaEnd = text.indexOf(\"</pre>\",encryptedStoreAreaStart);\n\t\tif(encryptedStoreAreaEnd !== -1) {\n\t\t\treturn $tw.utils.htmlDecode(text.substring(encryptedStoreAreaStart + encryptedStoreAreaStartMarker.length,encryptedStoreAreaEnd-1));\n\t\t}\n\t}\n\treturn null;\n};\n\n/*\nAttempt to extract the tiddlers from an encrypted store area using the current password. If the password is not provided then the password in the password store will be used\n*/\nexports.decryptStoreArea = function(encryptedStoreArea,password) {\n\tvar decryptedText = $tw.crypto.decrypt(encryptedStoreArea,password);\n\tif(decryptedText) {\n\t\tvar json = JSON.parse(decryptedText),\n\t\t\ttiddlers = [];\n\t\tfor(var title in json) {\n\t\t\tif(title !== \"$:/isEncrypted\") {\n\t\t\t\ttiddlers.push(json[title]);\n\t\t\t}\n\t\t}\n\t\treturn tiddlers;\n\t} else {\n\t\treturn null;\n\t}\n};\n\n\n/*\nAttempt to extract the tiddlers from an encrypted store area using the current password. If that fails, the user is prompted for a password.\nencryptedStoreArea: text of the TiddlyWiki encrypted store area\ncallback: function(tiddlers) called with the array of decrypted tiddlers\n\nThe following configuration settings are supported:\n\n$tw.config.usePasswordVault: causes any password entered by the user to also be put into the system password vault\n*/\nexports.decryptStoreAreaInteractive = function(encryptedStoreArea,callback,options) {\n\t// Try to decrypt with the current password\n\tvar tiddlers = $tw.utils.decryptStoreArea(encryptedStoreArea);\n\tif(tiddlers) {\n\t\tcallback(tiddlers);\n\t} else {\n\t\t// Prompt for a new password and keep trying\n\t\t$tw.passwordPrompt.createPrompt({\n\t\t\tserviceName: \"Enter a password to decrypt the imported TiddlyWiki\",\n\t\t\tnoUserName: true,\n\t\t\tcanCancel: true,\n\t\t\tsubmitText: \"Decrypt\",\n\t\t\tcallback: function(data) {\n\t\t\t\t// Exit if the user cancelled\n\t\t\t\tif(!data) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\t// Attempt to decrypt the tiddlers\n\t\t\t\tvar tiddlers = $tw.utils.decryptStoreArea(encryptedStoreArea,data.password);\n\t\t\t\tif(tiddlers) {\n\t\t\t\t\tif($tw.config.usePasswordVault) {\n\t\t\t\t\t\t$tw.crypto.setPassword(data.password);\n\t\t\t\t\t}\n\t\t\t\t\tcallback(tiddlers);\n\t\t\t\t\t// Exit and remove the password prompt\n\t\t\t\t\treturn true;\n\t\t\t\t} else {\n\t\t\t\t\t// We didn't decrypt everything, so continue to prompt for password\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "utils"
},
"$:/core/modules/utils/csv.js": {
"title": "$:/core/modules/utils/csv.js",
"text": "/*\\\ntitle: $:/core/modules/utils/csv.js\ntype: application/javascript\nmodule-type: utils\n\nA barebones CSV parser\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nParse a CSV string with a header row and return an array of hashmaps.\n*/\nexports.parseCsvStringWithHeader = function(text,options) {\n\toptions = options || {};\n\tvar separator = options.separator || \",\",\n\t\trows = text.split(/\\r?\\n/mg).map(function(row) {\n\t\t\treturn $tw.utils.trim(row);\n\t\t}).filter(function(row) {\n\t\t\treturn row !== \"\";\n\t\t});\n\tif(rows.length < 1) {\n\t\treturn \"Missing header row\";\n\t}\n\tvar headings = rows[0].split(separator),\n\t\tresults = [];\n\tfor(var row=1; row<rows.length; row++) {\n\t\tvar columns = rows[row].split(separator),\n\t\t\tcolumnResult = Object.create(null);\n\t\tif(columns.length !== headings.length) {\n\t\t\treturn \"Malformed CSV row '\" + rows[row] + \"'\";\n\t\t}\n\t\tfor(var column=0; column<columns.length; column++) {\n\t\t\tvar columnName = headings[column];\n\t\t\tcolumnResult[columnName] = $tw.utils.trim(columns[column] || \"\");\n\t\t}\n\t\tresults.push(columnResult);\t\t\t\n\t}\n\treturn results;\n}\n\n})();\n",
"type": "application/javascript",
"module-type": "utils"
},
"$:/core/modules/utils/diff-match-patch/diff_match_patch.js": {
"text": "(function(){function diff_match_patch(){this.Diff_Timeout=1;this.Diff_EditCost=4;this.Match_Threshold=.5;this.Match_Distance=1E3;this.Patch_DeleteThreshold=.5;this.Patch_Margin=4;this.Match_MaxBits=32}var DIFF_DELETE=-1,DIFF_INSERT=1,DIFF_EQUAL=0;\ndiff_match_patch.prototype.diff_main=function(a,b,c,d){\"undefined\"==typeof d&&(d=0>=this.Diff_Timeout?Number.MAX_VALUE:(new Date).getTime()+1E3*this.Diff_Timeout);if(null==a||null==b)throw Error(\"Null input. (diff_main)\");if(a==b)return a?[[DIFF_EQUAL,a]]:[];\"undefined\"==typeof c&&(c=!0);var e=c,f=this.diff_commonPrefix(a,b);c=a.substring(0,f);a=a.substring(f);b=b.substring(f);f=this.diff_commonSuffix(a,b);var g=a.substring(a.length-f);a=a.substring(0,a.length-f);b=b.substring(0,b.length-f);a=this.diff_compute_(a,\nb,e,d);c&&a.unshift([DIFF_EQUAL,c]);g&&a.push([DIFF_EQUAL,g]);this.diff_cleanupMerge(a);return a};\ndiff_match_patch.prototype.diff_compute_=function(a,b,c,d){if(!a)return[[DIFF_INSERT,b]];if(!b)return[[DIFF_DELETE,a]];var e=a.length>b.length?a:b,f=a.length>b.length?b:a,g=e.indexOf(f);return-1!=g?(c=[[DIFF_INSERT,e.substring(0,g)],[DIFF_EQUAL,f],[DIFF_INSERT,e.substring(g+f.length)]],a.length>b.length&&(c[0][0]=c[2][0]=DIFF_DELETE),c):1==f.length?[[DIFF_DELETE,a],[DIFF_INSERT,b]]:(e=this.diff_halfMatch_(a,b))?(b=e[1],f=e[3],a=e[4],e=this.diff_main(e[0],e[2],c,d),c=this.diff_main(b,f,c,d),e.concat([[DIFF_EQUAL,\na]],c)):c&&100<a.length&&100<b.length?this.diff_lineMode_(a,b,d):this.diff_bisect_(a,b,d)};\ndiff_match_patch.prototype.diff_lineMode_=function(a,b,c){var d=this.diff_linesToChars_(a,b);a=d.chars1;b=d.chars2;d=d.lineArray;a=this.diff_main(a,b,!1,c);this.diff_charsToLines_(a,d);this.diff_cleanupSemantic(a);a.push([DIFF_EQUAL,\"\"]);for(var e=d=b=0,f=\"\",g=\"\";b<a.length;){switch(a[b][0]){case DIFF_INSERT:e++;g+=a[b][1];break;case DIFF_DELETE:d++;f+=a[b][1];break;case DIFF_EQUAL:if(1<=d&&1<=e){a.splice(b-d-e,d+e);b=b-d-e;d=this.diff_main(f,g,!1,c);for(e=d.length-1;0<=e;e--)a.splice(b,0,d[e]);b+=\nd.length}d=e=0;g=f=\"\"}b++}a.pop();return a};\ndiff_match_patch.prototype.diff_bisect_=function(a,b,c){for(var d=a.length,e=b.length,f=Math.ceil((d+e)/2),g=2*f,h=Array(g),l=Array(g),k=0;k<g;k++)h[k]=-1,l[k]=-1;h[f+1]=0;l[f+1]=0;k=d-e;for(var m=0!=k%2,p=0,x=0,w=0,q=0,t=0;t<f&&!((new Date).getTime()>c);t++){for(var v=-t+p;v<=t-x;v+=2){var n=f+v;var r=v==-t||v!=t&&h[n-1]<h[n+1]?h[n+1]:h[n-1]+1;for(var y=r-v;r<d&&y<e&&a.charAt(r)==b.charAt(y);)r++,y++;h[n]=r;if(r>d)x+=2;else if(y>e)p+=2;else if(m&&(n=f+k-v,0<=n&&n<g&&-1!=l[n])){var u=d-l[n];if(r>=\nu)return this.diff_bisectSplit_(a,b,r,y,c)}}for(v=-t+w;v<=t-q;v+=2){n=f+v;u=v==-t||v!=t&&l[n-1]<l[n+1]?l[n+1]:l[n-1]+1;for(r=u-v;u<d&&r<e&&a.charAt(d-u-1)==b.charAt(e-r-1);)u++,r++;l[n]=u;if(u>d)q+=2;else if(r>e)w+=2;else if(!m&&(n=f+k-v,0<=n&&n<g&&-1!=h[n]&&(r=h[n],y=f+r-n,u=d-u,r>=u)))return this.diff_bisectSplit_(a,b,r,y,c)}}return[[DIFF_DELETE,a],[DIFF_INSERT,b]]};\ndiff_match_patch.prototype.diff_bisectSplit_=function(a,b,c,d,e){var f=a.substring(0,c),g=b.substring(0,d);a=a.substring(c);b=b.substring(d);f=this.diff_main(f,g,!1,e);e=this.diff_main(a,b,!1,e);return f.concat(e)};\ndiff_match_patch.prototype.diff_linesToChars_=function(a,b){function c(a){for(var b=\"\",c=0,f=-1,g=d.length;f<a.length-1;){f=a.indexOf(\"\\n\",c);-1==f&&(f=a.length-1);var h=a.substring(c,f+1);c=f+1;(e.hasOwnProperty?e.hasOwnProperty(h):void 0!==e[h])?b+=String.fromCharCode(e[h]):(b+=String.fromCharCode(g),e[h]=g,d[g++]=h)}return b}var d=[],e={};d[0]=\"\";var f=c(a),g=c(b);return{chars1:f,chars2:g,lineArray:d}};\ndiff_match_patch.prototype.diff_charsToLines_=function(a,b){for(var c=0;c<a.length;c++){for(var d=a[c][1],e=[],f=0;f<d.length;f++)e[f]=b[d.charCodeAt(f)];a[c][1]=e.join(\"\")}};diff_match_patch.prototype.diff_commonPrefix=function(a,b){if(!a||!b||a.charAt(0)!=b.charAt(0))return 0;for(var c=0,d=Math.min(a.length,b.length),e=d,f=0;c<e;)a.substring(f,e)==b.substring(f,e)?f=c=e:d=e,e=Math.floor((d-c)/2+c);return e};\ndiff_match_patch.prototype.diff_commonSuffix=function(a,b){if(!a||!b||a.charAt(a.length-1)!=b.charAt(b.length-1))return 0;for(var c=0,d=Math.min(a.length,b.length),e=d,f=0;c<e;)a.substring(a.length-e,a.length-f)==b.substring(b.length-e,b.length-f)?f=c=e:d=e,e=Math.floor((d-c)/2+c);return e};\ndiff_match_patch.prototype.diff_commonOverlap_=function(a,b){var c=a.length,d=b.length;if(0==c||0==d)return 0;c>d?a=a.substring(c-d):c<d&&(b=b.substring(0,c));c=Math.min(c,d);if(a==b)return c;d=0;for(var e=1;;){var f=a.substring(c-e);f=b.indexOf(f);if(-1==f)return d;e+=f;if(0==f||a.substring(c-e)==b.substring(0,e))d=e,e++}};\ndiff_match_patch.prototype.diff_halfMatch_=function(a,b){function c(a,b,c){for(var d=a.substring(c,c+Math.floor(a.length/4)),e=-1,g=\"\",h,k,l,m;-1!=(e=b.indexOf(d,e+1));){var p=f.diff_commonPrefix(a.substring(c),b.substring(e)),u=f.diff_commonSuffix(a.substring(0,c),b.substring(0,e));g.length<u+p&&(g=b.substring(e-u,e)+b.substring(e,e+p),h=a.substring(0,c-u),k=a.substring(c+p),l=b.substring(0,e-u),m=b.substring(e+p))}return 2*g.length>=a.length?[h,k,l,m,g]:null}if(0>=this.Diff_Timeout)return null;\nvar d=a.length>b.length?a:b,e=a.length>b.length?b:a;if(4>d.length||2*e.length<d.length)return null;var f=this,g=c(d,e,Math.ceil(d.length/4));d=c(d,e,Math.ceil(d.length/2));if(g||d)g=d?g?g[4].length>d[4].length?g:d:d:g;else return null;if(a.length>b.length){d=g[0];e=g[1];var h=g[2];var l=g[3]}else h=g[0],l=g[1],d=g[2],e=g[3];return[d,e,h,l,g[4]]};\ndiff_match_patch.prototype.diff_cleanupSemantic=function(a){for(var b=!1,c=[],d=0,e=null,f=0,g=0,h=0,l=0,k=0;f<a.length;)a[f][0]==DIFF_EQUAL?(c[d++]=f,g=l,h=k,k=l=0,e=a[f][1]):(a[f][0]==DIFF_INSERT?l+=a[f][1].length:k+=a[f][1].length,e&&e.length<=Math.max(g,h)&&e.length<=Math.max(l,k)&&(a.splice(c[d-1],0,[DIFF_DELETE,e]),a[c[d-1]+1][0]=DIFF_INSERT,d--,d--,f=0<d?c[d-1]:-1,k=l=h=g=0,e=null,b=!0)),f++;b&&this.diff_cleanupMerge(a);this.diff_cleanupSemanticLossless(a);for(f=1;f<a.length;){if(a[f-1][0]==\nDIFF_DELETE&&a[f][0]==DIFF_INSERT){b=a[f-1][1];c=a[f][1];d=this.diff_commonOverlap_(b,c);e=this.diff_commonOverlap_(c,b);if(d>=e){if(d>=b.length/2||d>=c.length/2)a.splice(f,0,[DIFF_EQUAL,c.substring(0,d)]),a[f-1][1]=b.substring(0,b.length-d),a[f+1][1]=c.substring(d),f++}else if(e>=b.length/2||e>=c.length/2)a.splice(f,0,[DIFF_EQUAL,b.substring(0,e)]),a[f-1][0]=DIFF_INSERT,a[f-1][1]=c.substring(0,c.length-e),a[f+1][0]=DIFF_DELETE,a[f+1][1]=b.substring(e),f++;f++}f++}};\ndiff_match_patch.prototype.diff_cleanupSemanticLossless=function(a){function b(a,b){if(!a||!b)return 6;var c=a.charAt(a.length-1),d=b.charAt(0),e=c.match(diff_match_patch.nonAlphaNumericRegex_),f=d.match(diff_match_patch.nonAlphaNumericRegex_),g=e&&c.match(diff_match_patch.whitespaceRegex_),h=f&&d.match(diff_match_patch.whitespaceRegex_);c=g&&c.match(diff_match_patch.linebreakRegex_);d=h&&d.match(diff_match_patch.linebreakRegex_);var k=c&&a.match(diff_match_patch.blanklineEndRegex_),l=d&&b.match(diff_match_patch.blanklineStartRegex_);\nreturn k||l?5:c||d?4:e&&!g&&h?3:g||h?2:e||f?1:0}for(var c=1;c<a.length-1;){if(a[c-1][0]==DIFF_EQUAL&&a[c+1][0]==DIFF_EQUAL){var d=a[c-1][1],e=a[c][1],f=a[c+1][1],g=this.diff_commonSuffix(d,e);if(g){var h=e.substring(e.length-g);d=d.substring(0,d.length-g);e=h+e.substring(0,e.length-g);f=h+f}g=d;h=e;for(var l=f,k=b(d,e)+b(e,f);e.charAt(0)===f.charAt(0);){d+=e.charAt(0);e=e.substring(1)+f.charAt(0);f=f.substring(1);var m=b(d,e)+b(e,f);m>=k&&(k=m,g=d,h=e,l=f)}a[c-1][1]!=g&&(g?a[c-1][1]=g:(a.splice(c-\n1,1),c--),a[c][1]=h,l?a[c+1][1]=l:(a.splice(c+1,1),c--))}c++}};diff_match_patch.nonAlphaNumericRegex_=/[^a-zA-Z0-9]/;diff_match_patch.whitespaceRegex_=/\\s/;diff_match_patch.linebreakRegex_=/[\\r\\n]/;diff_match_patch.blanklineEndRegex_=/\\n\\r?\\n$/;diff_match_patch.blanklineStartRegex_=/^\\r?\\n\\r?\\n/;\ndiff_match_patch.prototype.diff_cleanupEfficiency=function(a){for(var b=!1,c=[],d=0,e=null,f=0,g=!1,h=!1,l=!1,k=!1;f<a.length;)a[f][0]==DIFF_EQUAL?(a[f][1].length<this.Diff_EditCost&&(l||k)?(c[d++]=f,g=l,h=k,e=a[f][1]):(d=0,e=null),l=k=!1):(a[f][0]==DIFF_DELETE?k=!0:l=!0,e&&(g&&h&&l&&k||e.length<this.Diff_EditCost/2&&3==g+h+l+k)&&(a.splice(c[d-1],0,[DIFF_DELETE,e]),a[c[d-1]+1][0]=DIFF_INSERT,d--,e=null,g&&h?(l=k=!0,d=0):(d--,f=0<d?c[d-1]:-1,l=k=!1),b=!0)),f++;b&&this.diff_cleanupMerge(a)};\ndiff_match_patch.prototype.diff_cleanupMerge=function(a){a.push([DIFF_EQUAL,\"\"]);for(var b=0,c=0,d=0,e=\"\",f=\"\",g;b<a.length;)switch(a[b][0]){case DIFF_INSERT:d++;f+=a[b][1];b++;break;case DIFF_DELETE:c++;e+=a[b][1];b++;break;case DIFF_EQUAL:1<c+d?(0!==c&&0!==d&&(g=this.diff_commonPrefix(f,e),0!==g&&(0<b-c-d&&a[b-c-d-1][0]==DIFF_EQUAL?a[b-c-d-1][1]+=f.substring(0,g):(a.splice(0,0,[DIFF_EQUAL,f.substring(0,g)]),b++),f=f.substring(g),e=e.substring(g)),g=this.diff_commonSuffix(f,e),0!==g&&(a[b][1]=f.substring(f.length-\ng)+a[b][1],f=f.substring(0,f.length-g),e=e.substring(0,e.length-g))),0===c?a.splice(b-d,c+d,[DIFF_INSERT,f]):0===d?a.splice(b-c,c+d,[DIFF_DELETE,e]):a.splice(b-c-d,c+d,[DIFF_DELETE,e],[DIFF_INSERT,f]),b=b-c-d+(c?1:0)+(d?1:0)+1):0!==b&&a[b-1][0]==DIFF_EQUAL?(a[b-1][1]+=a[b][1],a.splice(b,1)):b++,c=d=0,f=e=\"\"}\"\"===a[a.length-1][1]&&a.pop();c=!1;for(b=1;b<a.length-1;)a[b-1][0]==DIFF_EQUAL&&a[b+1][0]==DIFF_EQUAL&&(a[b][1].substring(a[b][1].length-a[b-1][1].length)==a[b-1][1]?(a[b][1]=a[b-1][1]+a[b][1].substring(0,\na[b][1].length-a[b-1][1].length),a[b+1][1]=a[b-1][1]+a[b+1][1],a.splice(b-1,1),c=!0):a[b][1].substring(0,a[b+1][1].length)==a[b+1][1]&&(a[b-1][1]+=a[b+1][1],a[b][1]=a[b][1].substring(a[b+1][1].length)+a[b+1][1],a.splice(b+1,1),c=!0)),b++;c&&this.diff_cleanupMerge(a)};\ndiff_match_patch.prototype.diff_xIndex=function(a,b){var c=0,d=0,e=0,f=0,g;for(g=0;g<a.length;g++){a[g][0]!==DIFF_INSERT&&(c+=a[g][1].length);a[g][0]!==DIFF_DELETE&&(d+=a[g][1].length);if(c>b)break;e=c;f=d}return a.length!=g&&a[g][0]===DIFF_DELETE?f:f+(b-e)};\ndiff_match_patch.prototype.diff_prettyHtml=function(a){for(var b=[],c=/&/g,d=/</g,e=/>/g,f=/\\n/g,g=0;g<a.length;g++){var h=a[g][0],l=a[g][1].replace(c,\"&\").replace(d,\"<\").replace(e,\">\").replace(f,\"¶<br>\");switch(h){case DIFF_INSERT:b[g]='<ins style=\"background:#e6ffe6;\">'+l+\"</ins>\";break;case DIFF_DELETE:b[g]='<del style=\"background:#ffe6e6;\">'+l+\"</del>\";break;case DIFF_EQUAL:b[g]=\"<span>\"+l+\"</span>\"}}return b.join(\"\")};\ndiff_match_patch.prototype.diff_text1=function(a){for(var b=[],c=0;c<a.length;c++)a[c][0]!==DIFF_INSERT&&(b[c]=a[c][1]);return b.join(\"\")};diff_match_patch.prototype.diff_text2=function(a){for(var b=[],c=0;c<a.length;c++)a[c][0]!==DIFF_DELETE&&(b[c]=a[c][1]);return b.join(\"\")};\ndiff_match_patch.prototype.diff_levenshtein=function(a){for(var b=0,c=0,d=0,e=0;e<a.length;e++){var f=a[e][1];switch(a[e][0]){case DIFF_INSERT:c+=f.length;break;case DIFF_DELETE:d+=f.length;break;case DIFF_EQUAL:b+=Math.max(c,d),d=c=0}}return b+=Math.max(c,d)};\ndiff_match_patch.prototype.diff_toDelta=function(a){for(var b=[],c=0;c<a.length;c++)switch(a[c][0]){case DIFF_INSERT:b[c]=\"+\"+encodeURI(a[c][1]);break;case DIFF_DELETE:b[c]=\"-\"+a[c][1].length;break;case DIFF_EQUAL:b[c]=\"=\"+a[c][1].length}return b.join(\"\\t\").replace(/%20/g,\" \")};\ndiff_match_patch.prototype.diff_fromDelta=function(a,b){for(var c=[],d=0,e=0,f=b.split(/\\t/g),g=0;g<f.length;g++){var h=f[g].substring(1);switch(f[g].charAt(0)){case \"+\":try{c[d++]=[DIFF_INSERT,decodeURI(h)]}catch(k){throw Error(\"Illegal escape in diff_fromDelta: \"+h);}break;case \"-\":case \"=\":var l=parseInt(h,10);if(isNaN(l)||0>l)throw Error(\"Invalid number in diff_fromDelta: \"+h);h=a.substring(e,e+=l);\"=\"==f[g].charAt(0)?c[d++]=[DIFF_EQUAL,h]:c[d++]=[DIFF_DELETE,h];break;default:if(f[g])throw Error(\"Invalid diff operation in diff_fromDelta: \"+\nf[g]);}}if(e!=a.length)throw Error(\"Delta length (\"+e+\") does not equal source text length (\"+a.length+\").\");return c};diff_match_patch.prototype.match_main=function(a,b,c){if(null==a||null==b||null==c)throw Error(\"Null input. (match_main)\");c=Math.max(0,Math.min(c,a.length));return a==b?0:a.length?a.substring(c,c+b.length)==b?c:this.match_bitap_(a,b,c):-1};\ndiff_match_patch.prototype.match_bitap_=function(a,b,c){function d(a,d){var e=a/b.length,g=Math.abs(c-d);return f.Match_Distance?e+g/f.Match_Distance:g?1:e}if(b.length>this.Match_MaxBits)throw Error(\"Pattern too long for this browser.\");var e=this.match_alphabet_(b),f=this,g=this.Match_Threshold,h=a.indexOf(b,c);-1!=h&&(g=Math.min(d(0,h),g),h=a.lastIndexOf(b,c+b.length),-1!=h&&(g=Math.min(d(0,h),g)));var l=1<<b.length-1;h=-1;for(var k,m,p=b.length+a.length,x,w=0;w<b.length;w++){k=0;for(m=p;k<m;)d(w,\nc+m)<=g?k=m:p=m,m=Math.floor((p-k)/2+k);p=m;k=Math.max(1,c-m+1);var q=Math.min(c+m,a.length)+b.length;m=Array(q+2);for(m[q+1]=(1<<w)-1;q>=k;q--){var t=e[a.charAt(q-1)];m[q]=0===w?(m[q+1]<<1|1)&t:(m[q+1]<<1|1)&t|(x[q+1]|x[q])<<1|1|x[q+1];if(m[q]&l&&(t=d(w,q-1),t<=g))if(g=t,h=q-1,h>c)k=Math.max(1,2*c-h);else break}if(d(w+1,c)>g)break;x=m}return h};\ndiff_match_patch.prototype.match_alphabet_=function(a){for(var b={},c=0;c<a.length;c++)b[a.charAt(c)]=0;for(c=0;c<a.length;c++)b[a.charAt(c)]|=1<<a.length-c-1;return b};\ndiff_match_patch.prototype.patch_addContext_=function(a,b){if(0!=b.length){for(var c=b.substring(a.start2,a.start2+a.length1),d=0;b.indexOf(c)!=b.lastIndexOf(c)&&c.length<this.Match_MaxBits-this.Patch_Margin-this.Patch_Margin;)d+=this.Patch_Margin,c=b.substring(a.start2-d,a.start2+a.length1+d);d+=this.Patch_Margin;(c=b.substring(a.start2-d,a.start2))&&a.diffs.unshift([DIFF_EQUAL,c]);(d=b.substring(a.start2+a.length1,a.start2+a.length1+d))&&a.diffs.push([DIFF_EQUAL,d]);a.start1-=c.length;a.start2-=\nc.length;a.length1+=c.length+d.length;a.length2+=c.length+d.length}};\ndiff_match_patch.prototype.patch_make=function(a,b,c){if(\"string\"==typeof a&&\"string\"==typeof b&&\"undefined\"==typeof c){var d=a;b=this.diff_main(d,b,!0);2<b.length&&(this.diff_cleanupSemantic(b),this.diff_cleanupEfficiency(b))}else if(a&&\"object\"==typeof a&&\"undefined\"==typeof b&&\"undefined\"==typeof c)b=a,d=this.diff_text1(b);else if(\"string\"==typeof a&&b&&\"object\"==typeof b&&\"undefined\"==typeof c)d=a;else if(\"string\"==typeof a&&\"string\"==typeof b&&c&&\"object\"==typeof c)d=a,b=c;else throw Error(\"Unknown call format to patch_make.\");\nif(0===b.length)return[];c=[];a=new diff_match_patch.patch_obj;for(var e=0,f=0,g=0,h=d,l=0;l<b.length;l++){var k=b[l][0],m=b[l][1];e||k===DIFF_EQUAL||(a.start1=f,a.start2=g);switch(k){case DIFF_INSERT:a.diffs[e++]=b[l];a.length2+=m.length;d=d.substring(0,g)+m+d.substring(g);break;case DIFF_DELETE:a.length1+=m.length;a.diffs[e++]=b[l];d=d.substring(0,g)+d.substring(g+m.length);break;case DIFF_EQUAL:m.length<=2*this.Patch_Margin&&e&&b.length!=l+1?(a.diffs[e++]=b[l],a.length1+=m.length,a.length2+=m.length):\nm.length>=2*this.Patch_Margin&&e&&(this.patch_addContext_(a,h),c.push(a),a=new diff_match_patch.patch_obj,e=0,h=d,f=g)}k!==DIFF_INSERT&&(f+=m.length);k!==DIFF_DELETE&&(g+=m.length)}e&&(this.patch_addContext_(a,h),c.push(a));return c};\ndiff_match_patch.prototype.patch_deepCopy=function(a){for(var b=[],c=0;c<a.length;c++){var d=a[c],e=new diff_match_patch.patch_obj;e.diffs=[];for(var f=0;f<d.diffs.length;f++)e.diffs[f]=d.diffs[f].slice();e.start1=d.start1;e.start2=d.start2;e.length1=d.length1;e.length2=d.length2;b[c]=e}return b};\ndiff_match_patch.prototype.patch_apply=function(a,b){if(0==a.length)return[b,[]];a=this.patch_deepCopy(a);var c=this.patch_addPadding(a);b=c+b+c;this.patch_splitMax(a);for(var d=0,e=[],f=0;f<a.length;f++){var g=a[f].start2+d,h=this.diff_text1(a[f].diffs),l=-1;if(h.length>this.Match_MaxBits){var k=this.match_main(b,h.substring(0,this.Match_MaxBits),g);-1!=k&&(l=this.match_main(b,h.substring(h.length-this.Match_MaxBits),g+h.length-this.Match_MaxBits),-1==l||k>=l)&&(k=-1)}else k=this.match_main(b,h,\ng);if(-1==k)e[f]=!1,d-=a[f].length2-a[f].length1;else if(e[f]=!0,d=k-g,g=-1==l?b.substring(k,k+h.length):b.substring(k,l+this.Match_MaxBits),h==g)b=b.substring(0,k)+this.diff_text2(a[f].diffs)+b.substring(k+h.length);else if(g=this.diff_main(h,g,!1),h.length>this.Match_MaxBits&&this.diff_levenshtein(g)/h.length>this.Patch_DeleteThreshold)e[f]=!1;else{this.diff_cleanupSemanticLossless(g);h=0;var m;for(l=0;l<a[f].diffs.length;l++){var p=a[f].diffs[l];p[0]!==DIFF_EQUAL&&(m=this.diff_xIndex(g,h));p[0]===\nDIFF_INSERT?b=b.substring(0,k+m)+p[1]+b.substring(k+m):p[0]===DIFF_DELETE&&(b=b.substring(0,k+m)+b.substring(k+this.diff_xIndex(g,h+p[1].length)));p[0]!==DIFF_DELETE&&(h+=p[1].length)}}}b=b.substring(c.length,b.length-c.length);return[b,e]};\ndiff_match_patch.prototype.patch_addPadding=function(a){for(var b=this.Patch_Margin,c=\"\",d=1;d<=b;d++)c+=String.fromCharCode(d);for(d=0;d<a.length;d++)a[d].start1+=b,a[d].start2+=b;d=a[0];var e=d.diffs;if(0==e.length||e[0][0]!=DIFF_EQUAL)e.unshift([DIFF_EQUAL,c]),d.start1-=b,d.start2-=b,d.length1+=b,d.length2+=b;else if(b>e[0][1].length){var f=b-e[0][1].length;e[0][1]=c.substring(e[0][1].length)+e[0][1];d.start1-=f;d.start2-=f;d.length1+=f;d.length2+=f}d=a[a.length-1];e=d.diffs;0==e.length||e[e.length-\n1][0]!=DIFF_EQUAL?(e.push([DIFF_EQUAL,c]),d.length1+=b,d.length2+=b):b>e[e.length-1][1].length&&(f=b-e[e.length-1][1].length,e[e.length-1][1]+=c.substring(0,f),d.length1+=f,d.length2+=f);return c};\ndiff_match_patch.prototype.patch_splitMax=function(a){for(var b=this.Match_MaxBits,c=0;c<a.length;c++)if(!(a[c].length1<=b)){var d=a[c];a.splice(c--,1);for(var e=d.start1,f=d.start2,g=\"\";0!==d.diffs.length;){var h=new diff_match_patch.patch_obj,l=!0;h.start1=e-g.length;h.start2=f-g.length;\"\"!==g&&(h.length1=h.length2=g.length,h.diffs.push([DIFF_EQUAL,g]));for(;0!==d.diffs.length&&h.length1<b-this.Patch_Margin;){g=d.diffs[0][0];var k=d.diffs[0][1];g===DIFF_INSERT?(h.length2+=k.length,f+=k.length,h.diffs.push(d.diffs.shift()),\nl=!1):g===DIFF_DELETE&&1==h.diffs.length&&h.diffs[0][0]==DIFF_EQUAL&&k.length>2*b?(h.length1+=k.length,e+=k.length,l=!1,h.diffs.push([g,k]),d.diffs.shift()):(k=k.substring(0,b-h.length1-this.Patch_Margin),h.length1+=k.length,e+=k.length,g===DIFF_EQUAL?(h.length2+=k.length,f+=k.length):l=!1,h.diffs.push([g,k]),k==d.diffs[0][1]?d.diffs.shift():d.diffs[0][1]=d.diffs[0][1].substring(k.length))}g=this.diff_text2(h.diffs);g=g.substring(g.length-this.Patch_Margin);k=this.diff_text1(d.diffs).substring(0,\nthis.Patch_Margin);\"\"!==k&&(h.length1+=k.length,h.length2+=k.length,0!==h.diffs.length&&h.diffs[h.diffs.length-1][0]===DIFF_EQUAL?h.diffs[h.diffs.length-1][1]+=k:h.diffs.push([DIFF_EQUAL,k]));l||a.splice(++c,0,h)}}};diff_match_patch.prototype.patch_toText=function(a){for(var b=[],c=0;c<a.length;c++)b[c]=a[c];return b.join(\"\")};\ndiff_match_patch.prototype.patch_fromText=function(a){var b=[];if(!a)return b;a=a.split(\"\\n\");for(var c=0,d=/^@@ -(\\d+),?(\\d*) \\+(\\d+),?(\\d*) @@$/;c<a.length;){var e=a[c].match(d);if(!e)throw Error(\"Invalid patch string: \"+a[c]);var f=new diff_match_patch.patch_obj;b.push(f);f.start1=parseInt(e[1],10);\"\"===e[2]?(f.start1--,f.length1=1):\"0\"==e[2]?f.length1=0:(f.start1--,f.length1=parseInt(e[2],10));f.start2=parseInt(e[3],10);\"\"===e[4]?(f.start2--,f.length2=1):\"0\"==e[4]?f.length2=0:(f.start2--,f.length2=\nparseInt(e[4],10));for(c++;c<a.length;){e=a[c].charAt(0);try{var g=decodeURI(a[c].substring(1))}catch(h){throw Error(\"Illegal escape in patch_fromText: \"+g);}if(\"-\"==e)f.diffs.push([DIFF_DELETE,g]);else if(\"+\"==e)f.diffs.push([DIFF_INSERT,g]);else if(\" \"==e)f.diffs.push([DIFF_EQUAL,g]);else if(\"@\"==e)break;else if(\"\"!==e)throw Error('Invalid patch mode \"'+e+'\" in: '+g);c++}}return b};diff_match_patch.patch_obj=function(){this.diffs=[];this.start2=this.start1=null;this.length2=this.length1=0};\ndiff_match_patch.patch_obj.prototype.toString=function(){for(var a=[\"@@ -\"+(0===this.length1?this.start1+\",0\":1==this.length1?this.start1+1:this.start1+1+\",\"+this.length1)+\" +\"+(0===this.length2?this.start2+\",0\":1==this.length2?this.start2+1:this.start2+1+\",\"+this.length2)+\" @@\\n\"],b,c=0;c<this.diffs.length;c++){switch(this.diffs[c][0]){case DIFF_INSERT:b=\"+\";break;case DIFF_DELETE:b=\"-\";break;case DIFF_EQUAL:b=\" \"}a[c+1]=b+encodeURI(this.diffs[c][1])+\"\\n\"}return a.join(\"\").replace(/%20/g,\" \")};\nthis.diff_match_patch=diff_match_patch;this.DIFF_DELETE=DIFF_DELETE;this.DIFF_INSERT=DIFF_INSERT;this.DIFF_EQUAL=DIFF_EQUAL;\n}).call(exports);",
"type": "application/javascript",
"title": "$:/core/modules/utils/diff-match-patch/diff_match_patch.js",
"module-type": "library"
},
"$:/core/modules/utils/dom/animations/slide.js": {
"title": "$:/core/modules/utils/dom/animations/slide.js",
"text": "/*\\\ntitle: $:/core/modules/utils/dom/animations/slide.js\ntype: application/javascript\nmodule-type: animation\n\nA simple slide animation that varies the height of the element\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nfunction slideOpen(domNode,options) {\n\toptions = options || {};\n\tvar duration = options.duration || $tw.utils.getAnimationDuration();\n\t// Get the current height of the domNode\n\tvar computedStyle = window.getComputedStyle(domNode),\n\t\tcurrMarginBottom = parseInt(computedStyle.marginBottom,10),\n\t\tcurrMarginTop = parseInt(computedStyle.marginTop,10),\n\t\tcurrPaddingBottom = parseInt(computedStyle.paddingBottom,10),\n\t\tcurrPaddingTop = parseInt(computedStyle.paddingTop,10),\n\t\tcurrHeight = domNode.offsetHeight;\n\t// Reset the margin once the transition is over\n\tsetTimeout(function() {\n\t\t$tw.utils.setStyle(domNode,[\n\t\t\t{transition: \"none\"},\n\t\t\t{marginBottom: \"\"},\n\t\t\t{marginTop: \"\"},\n\t\t\t{paddingBottom: \"\"},\n\t\t\t{paddingTop: \"\"},\n\t\t\t{height: \"auto\"},\n\t\t\t{opacity: \"\"}\n\t\t]);\n\t\tif(options.callback) {\n\t\t\toptions.callback();\n\t\t}\n\t},duration);\n\t// Set up the initial position of the element\n\t$tw.utils.setStyle(domNode,[\n\t\t{transition: \"none\"},\n\t\t{marginTop: \"0px\"},\n\t\t{marginBottom: \"0px\"},\n\t\t{paddingTop: \"0px\"},\n\t\t{paddingBottom: \"0px\"},\n\t\t{height: \"0px\"},\n\t\t{opacity: \"0\"}\n\t]);\n\t$tw.utils.forceLayout(domNode);\n\t// Transition to the final position\n\t$tw.utils.setStyle(domNode,[\n\t\t{transition: \"margin-top \" + duration + \"ms ease-in-out, \" +\n\t\t\t\t\t\"margin-bottom \" + duration + \"ms ease-in-out, \" +\n\t\t\t\t\t\"padding-top \" + duration + \"ms ease-in-out, \" +\n\t\t\t\t\t\"padding-bottom \" + duration + \"ms ease-in-out, \" +\n\t\t\t\t\t\"height \" + duration + \"ms ease-in-out, \" +\n\t\t\t\t\t\"opacity \" + duration + \"ms ease-in-out\"},\n\t\t{marginBottom: currMarginBottom + \"px\"},\n\t\t{marginTop: currMarginTop + \"px\"},\n\t\t{paddingBottom: currPaddingBottom + \"px\"},\n\t\t{paddingTop: currPaddingTop + \"px\"},\n\t\t{height: currHeight + \"px\"},\n\t\t{opacity: \"1\"}\n\t]);\n}\n\nfunction slideClosed(domNode,options) {\n\toptions = options || {};\n\tvar duration = options.duration || $tw.utils.getAnimationDuration(),\n\t\tcurrHeight = domNode.offsetHeight;\n\t// Clear the properties we've set when the animation is over\n\tsetTimeout(function() {\n\t\t$tw.utils.setStyle(domNode,[\n\t\t\t{transition: \"none\"},\n\t\t\t{marginBottom: \"\"},\n\t\t\t{marginTop: \"\"},\n\t\t\t{paddingBottom: \"\"},\n\t\t\t{paddingTop: \"\"},\n\t\t\t{height: \"auto\"},\n\t\t\t{opacity: \"\"}\n\t\t]);\n\t\tif(options.callback) {\n\t\t\toptions.callback();\n\t\t}\n\t},duration);\n\t// Set up the initial position of the element\n\t$tw.utils.setStyle(domNode,[\n\t\t{height: currHeight + \"px\"},\n\t\t{opacity: \"1\"}\n\t]);\n\t$tw.utils.forceLayout(domNode);\n\t// Transition to the final position\n\t$tw.utils.setStyle(domNode,[\n\t\t{transition: \"margin-top \" + duration + \"ms ease-in-out, \" +\n\t\t\t\t\t\"margin-bottom \" + duration + \"ms ease-in-out, \" +\n\t\t\t\t\t\"padding-top \" + duration + \"ms ease-in-out, \" +\n\t\t\t\t\t\"padding-bottom \" + duration + \"ms ease-in-out, \" +\n\t\t\t\t\t\"height \" + duration + \"ms ease-in-out, \" +\n\t\t\t\t\t\"opacity \" + duration + \"ms ease-in-out\"},\n\t\t{marginTop: \"0px\"},\n\t\t{marginBottom: \"0px\"},\n\t\t{paddingTop: \"0px\"},\n\t\t{paddingBottom: \"0px\"},\n\t\t{height: \"0px\"},\n\t\t{opacity: \"0\"}\n\t]);\n}\n\nexports.slide = {\n\topen: slideOpen,\n\tclose: slideClosed\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "animation"
},
"$:/core/modules/utils/dom/animator.js": {
"title": "$:/core/modules/utils/dom/animator.js",
"text": "/*\\\ntitle: $:/core/modules/utils/dom/animator.js\ntype: application/javascript\nmodule-type: utils\n\nOrchestrates animations and transitions\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nfunction Animator() {\n\t// Get the registered animation modules\n\tthis.animations = {};\n\t$tw.modules.applyMethods(\"animation\",this.animations);\n}\n\nAnimator.prototype.perform = function(type,domNode,options) {\n\toptions = options || {};\n\t// Find an animation that can handle this type\n\tvar chosenAnimation;\n\t$tw.utils.each(this.animations,function(animation,name) {\n\t\tif($tw.utils.hop(animation,type)) {\n\t\t\tchosenAnimation = animation[type];\n\t\t}\n\t});\n\tif(!chosenAnimation) {\n\t\tchosenAnimation = function(domNode,options) {\n\t\t\tif(options.callback) {\n\t\t\t\toptions.callback();\n\t\t\t}\n\t\t};\n\t}\n\t// Call the animation\n\tchosenAnimation(domNode,options);\n};\n\nexports.Animator = Animator;\n\n})();\n",
"type": "application/javascript",
"module-type": "utils"
},
"$:/core/modules/utils/dom/browser.js": {
"title": "$:/core/modules/utils/dom/browser.js",
"text": "/*\\\ntitle: $:/core/modules/utils/dom/browser.js\ntype: application/javascript\nmodule-type: utils\n\nBrowser feature detection\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nSet style properties of an element\n\telement: dom node\n\tstyles: ordered array of {name: value} pairs\n*/\nexports.setStyle = function(element,styles) {\n\tif(element.nodeType === 1) { // Element.ELEMENT_NODE\n\t\tfor(var t=0; t<styles.length; t++) {\n\t\t\tfor(var styleName in styles[t]) {\n\t\t\t\telement.style[$tw.utils.convertStyleNameToPropertyName(styleName)] = styles[t][styleName];\n\t\t\t}\n\t\t}\n\t}\n};\n\n/*\nConverts a standard CSS property name into the local browser-specific equivalent. For example:\n\t\"background-color\" --> \"backgroundColor\"\n\t\"transition\" --> \"webkitTransition\"\n*/\n\nvar styleNameCache = {}; // We'll cache the style name conversions\n\nexports.convertStyleNameToPropertyName = function(styleName) {\n\t// Return from the cache if we can\n\tif(styleNameCache[styleName]) {\n\t\treturn styleNameCache[styleName];\n\t}\n\t// Convert it by first removing any hyphens\n\tvar propertyName = $tw.utils.unHyphenateCss(styleName);\n\t// Then check if it needs a prefix\n\tif($tw.browser && document.body.style[propertyName] === undefined) {\n\t\tvar prefixes = [\"O\",\"MS\",\"Moz\",\"webkit\"];\n\t\tfor(var t=0; t<prefixes.length; t++) {\n\t\t\tvar prefixedName = prefixes[t] + propertyName.substr(0,1).toUpperCase() + propertyName.substr(1);\n\t\t\tif(document.body.style[prefixedName] !== undefined) {\n\t\t\t\tpropertyName = prefixedName;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\t// Put it in the cache too\n\tstyleNameCache[styleName] = propertyName;\n\treturn propertyName;\n};\n\n/*\nConverts a JS format CSS property name back into the dashed form used in CSS declarations. For example:\n\t\"backgroundColor\" --> \"background-color\"\n\t\"webkitTransform\" --> \"-webkit-transform\"\n*/\nexports.convertPropertyNameToStyleName = function(propertyName) {\n\t// Rehyphenate the name\n\tvar styleName = $tw.utils.hyphenateCss(propertyName);\n\t// If there's a webkit prefix, add a dash (other browsers have uppercase prefixes, and so get the dash automatically)\n\tif(styleName.indexOf(\"webkit\") === 0) {\n\t\tstyleName = \"-\" + styleName;\n\t} else if(styleName.indexOf(\"-m-s\") === 0) {\n\t\tstyleName = \"-ms\" + styleName.substr(4);\n\t}\n\treturn styleName;\n};\n\n/*\nRound trip a stylename to a property name and back again. For example:\n\t\"transform\" --> \"webkitTransform\" --> \"-webkit-transform\"\n*/\nexports.roundTripPropertyName = function(propertyName) {\n\treturn $tw.utils.convertPropertyNameToStyleName($tw.utils.convertStyleNameToPropertyName(propertyName));\n};\n\n/*\nConverts a standard event name into the local browser specific equivalent. For example:\n\t\"animationEnd\" --> \"webkitAnimationEnd\"\n*/\n\nvar eventNameCache = {}; // We'll cache the conversions\n\nvar eventNameMappings = {\n\t\"transitionEnd\": {\n\t\tcorrespondingCssProperty: \"transition\",\n\t\tmappings: {\n\t\t\ttransition: \"transitionend\",\n\t\t\tOTransition: \"oTransitionEnd\",\n\t\t\tMSTransition: \"msTransitionEnd\",\n\t\t\tMozTransition: \"transitionend\",\n\t\t\twebkitTransition: \"webkitTransitionEnd\"\n\t\t}\n\t},\n\t\"animationEnd\": {\n\t\tcorrespondingCssProperty: \"animation\",\n\t\tmappings: {\n\t\t\tanimation: \"animationend\",\n\t\t\tOAnimation: \"oAnimationEnd\",\n\t\t\tMSAnimation: \"msAnimationEnd\",\n\t\t\tMozAnimation: \"animationend\",\n\t\t\twebkitAnimation: \"webkitAnimationEnd\"\n\t\t}\n\t}\n};\n\nexports.convertEventName = function(eventName) {\n\tif(eventNameCache[eventName]) {\n\t\treturn eventNameCache[eventName];\n\t}\n\tvar newEventName = eventName,\n\t\tmappings = eventNameMappings[eventName];\n\tif(mappings) {\n\t\tvar convertedProperty = $tw.utils.convertStyleNameToPropertyName(mappings.correspondingCssProperty);\n\t\tif(mappings.mappings[convertedProperty]) {\n\t\t\tnewEventName = mappings.mappings[convertedProperty];\n\t\t}\n\t}\n\t// Put it in the cache too\n\teventNameCache[eventName] = newEventName;\n\treturn newEventName;\n};\n\n/*\nReturn the names of the fullscreen APIs\n*/\nexports.getFullScreenApis = function() {\n\tvar d = document,\n\t\tdb = d.body,\n\t\tresult = {\n\t\t\"_requestFullscreen\": db.webkitRequestFullscreen !== undefined ? \"webkitRequestFullscreen\" :\n\t\t\t\t\t\t\tdb.mozRequestFullScreen !== undefined ? \"mozRequestFullScreen\" :\n\t\t\t\t\t\t\tdb.msRequestFullscreen !== undefined ? \"msRequestFullscreen\" :\n\t\t\t\t\t\t\tdb.requestFullscreen !== undefined ? \"requestFullscreen\" : \"\",\n\t\t\"_exitFullscreen\": d.webkitExitFullscreen !== undefined ? \"webkitExitFullscreen\" :\n\t\t\t\t\t\t\td.mozCancelFullScreen !== undefined ? \"mozCancelFullScreen\" :\n\t\t\t\t\t\t\td.msExitFullscreen !== undefined ? \"msExitFullscreen\" :\n\t\t\t\t\t\t\td.exitFullscreen !== undefined ? \"exitFullscreen\" : \"\",\n\t\t\"_fullscreenElement\": d.webkitFullscreenElement !== undefined ? \"webkitFullscreenElement\" :\n\t\t\t\t\t\t\td.mozFullScreenElement !== undefined ? \"mozFullScreenElement\" :\n\t\t\t\t\t\t\td.msFullscreenElement !== undefined ? \"msFullscreenElement\" :\n\t\t\t\t\t\t\td.fullscreenElement !== undefined ? \"fullscreenElement\" : \"\",\n\t\t\"_fullscreenChange\": d.webkitFullscreenElement !== undefined ? \"webkitfullscreenchange\" :\n\t\t\t\t\t\t\td.mozFullScreenElement !== undefined ? \"mozfullscreenchange\" :\n\t\t\t\t\t\t\td.msFullscreenElement !== undefined ? \"MSFullscreenChange\" :\n\t\t\t\t\t\t\td.fullscreenElement !== undefined ? \"fullscreenchange\" : \"\"\n\t};\n\tif(!result._requestFullscreen || !result._exitFullscreen || !result._fullscreenElement || !result._fullscreenChange) {\n\t\treturn null;\n\t} else {\n\t\treturn result;\n\t}\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "utils"
},
"$:/core/modules/utils/dom/csscolorparser.js": {
"title": "$:/core/modules/utils/dom/csscolorparser.js",
"text": "// (c) Dean McNamee <dean@gmail.com>, 2012.\n//\n// https://github.com/deanm/css-color-parser-js\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal in the Software without restriction, including without limitation the\n// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n// sell copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n// IN THE SOFTWARE.\n\n// http://www.w3.org/TR/css3-color/\nvar kCSSColorTable = {\n \"transparent\": [0,0,0,0], \"aliceblue\": [240,248,255,1],\n \"antiquewhite\": [250,235,215,1], \"aqua\": [0,255,255,1],\n \"aquamarine\": [127,255,212,1], \"azure\": [240,255,255,1],\n \"beige\": [245,245,220,1], \"bisque\": [255,228,196,1],\n \"black\": [0,0,0,1], \"blanchedalmond\": [255,235,205,1],\n \"blue\": [0,0,255,1], \"blueviolet\": [138,43,226,1],\n \"brown\": [165,42,42,1], \"burlywood\": [222,184,135,1],\n \"cadetblue\": [95,158,160,1], \"chartreuse\": [127,255,0,1],\n \"chocolate\": [210,105,30,1], \"coral\": [255,127,80,1],\n \"cornflowerblue\": [100,149,237,1], \"cornsilk\": [255,248,220,1],\n \"crimson\": [220,20,60,1], \"cyan\": [0,255,255,1],\n \"darkblue\": [0,0,139,1], \"darkcyan\": [0,139,139,1],\n \"darkgoldenrod\": [184,134,11,1], \"darkgray\": [169,169,169,1],\n \"darkgreen\": [0,100,0,1], \"darkgrey\": [169,169,169,1],\n \"darkkhaki\": [189,183,107,1], \"darkmagenta\": [139,0,139,1],\n \"darkolivegreen\": [85,107,47,1], \"darkorange\": [255,140,0,1],\n \"darkorchid\": [153,50,204,1], \"darkred\": [139,0,0,1],\n \"darksalmon\": [233,150,122,1], \"darkseagreen\": [143,188,143,1],\n \"darkslateblue\": [72,61,139,1], \"darkslategray\": [47,79,79,1],\n \"darkslategrey\": [47,79,79,1], \"darkturquoise\": [0,206,209,1],\n \"darkviolet\": [148,0,211,1], \"deeppink\": [255,20,147,1],\n \"deepskyblue\": [0,191,255,1], \"dimgray\": [105,105,105,1],\n \"dimgrey\": [105,105,105,1], \"dodgerblue\": [30,144,255,1],\n \"firebrick\": [178,34,34,1], \"floralwhite\": [255,250,240,1],\n \"forestgreen\": [34,139,34,1], \"fuchsia\": [255,0,255,1],\n \"gainsboro\": [220,220,220,1], \"ghostwhite\": [248,248,255,1],\n \"gold\": [255,215,0,1], \"goldenrod\": [218,165,32,1],\n \"gray\": [128,128,128,1], \"green\": [0,128,0,1],\n \"greenyellow\": [173,255,47,1], \"grey\": [128,128,128,1],\n \"honeydew\": [240,255,240,1], \"hotpink\": [255,105,180,1],\n \"indianred\": [205,92,92,1], \"indigo\": [75,0,130,1],\n \"ivory\": [255,255,240,1], \"khaki\": [240,230,140,1],\n \"lavender\": [230,230,250,1], \"lavenderblush\": [255,240,245,1],\n \"lawngreen\": [124,252,0,1], \"lemonchiffon\": [255,250,205,1],\n \"lightblue\": [173,216,230,1], \"lightcoral\": [240,128,128,1],\n \"lightcyan\": [224,255,255,1], \"lightgoldenrodyellow\": [250,250,210,1],\n \"lightgray\": [211,211,211,1], \"lightgreen\": [144,238,144,1],\n \"lightgrey\": [211,211,211,1], \"lightpink\": [255,182,193,1],\n \"lightsalmon\": [255,160,122,1], \"lightseagreen\": [32,178,170,1],\n \"lightskyblue\": [135,206,250,1], \"lightslategray\": [119,136,153,1],\n \"lightslategrey\": [119,136,153,1], \"lightsteelblue\": [176,196,222,1],\n \"lightyellow\": [255,255,224,1], \"lime\": [0,255,0,1],\n \"limegreen\": [50,205,50,1], \"linen\": [250,240,230,1],\n \"magenta\": [255,0,255,1], \"maroon\": [128,0,0,1],\n \"mediumaquamarine\": [102,205,170,1], \"mediumblue\": [0,0,205,1],\n \"mediumorchid\": [186,85,211,1], \"mediumpurple\": [147,112,219,1],\n \"mediumseagreen\": [60,179,113,1], \"mediumslateblue\": [123,104,238,1],\n \"mediumspringgreen\": [0,250,154,1], \"mediumturquoise\": [72,209,204,1],\n \"mediumvioletred\": [199,21,133,1], \"midnightblue\": [25,25,112,1],\n \"mintcream\": [245,255,250,1], \"mistyrose\": [255,228,225,1],\n \"moccasin\": [255,228,181,1], \"navajowhite\": [255,222,173,1],\n \"navy\": [0,0,128,1], \"oldlace\": [253,245,230,1],\n \"olive\": [128,128,0,1], \"olivedrab\": [107,142,35,1],\n \"orange\": [255,165,0,1], \"orangered\": [255,69,0,1],\n \"orchid\": [218,112,214,1], \"palegoldenrod\": [238,232,170,1],\n \"palegreen\": [152,251,152,1], \"paleturquoise\": [175,238,238,1],\n \"palevioletred\": [219,112,147,1], \"papayawhip\": [255,239,213,1],\n \"peachpuff\": [255,218,185,1], \"peru\": [205,133,63,1],\n \"pink\": [255,192,203,1], \"plum\": [221,160,221,1],\n \"powderblue\": [176,224,230,1], \"purple\": [128,0,128,1],\n \"red\": [255,0,0,1], \"rosybrown\": [188,143,143,1],\n \"royalblue\": [65,105,225,1], \"saddlebrown\": [139,69,19,1],\n \"salmon\": [250,128,114,1], \"sandybrown\": [244,164,96,1],\n \"seagreen\": [46,139,87,1], \"seashell\": [255,245,238,1],\n \"sienna\": [160,82,45,1], \"silver\": [192,192,192,1],\n \"skyblue\": [135,206,235,1], \"slateblue\": [106,90,205,1],\n \"slategray\": [112,128,144,1], \"slategrey\": [112,128,144,1],\n \"snow\": [255,250,250,1], \"springgreen\": [0,255,127,1],\n \"steelblue\": [70,130,180,1], \"tan\": [210,180,140,1],\n \"teal\": [0,128,128,1], \"thistle\": [216,191,216,1],\n \"tomato\": [255,99,71,1], \"turquoise\": [64,224,208,1],\n \"violet\": [238,130,238,1], \"wheat\": [245,222,179,1],\n \"white\": [255,255,255,1], \"whitesmoke\": [245,245,245,1],\n \"yellow\": [255,255,0,1], \"yellowgreen\": [154,205,50,1]}\n\nfunction clamp_css_byte(i) { // Clamp to integer 0 .. 255.\n i = Math.round(i); // Seems to be what Chrome does (vs truncation).\n return i < 0 ? 0 : i > 255 ? 255 : i;\n}\n\nfunction clamp_css_float(f) { // Clamp to float 0.0 .. 1.0.\n return f < 0 ? 0 : f > 1 ? 1 : f;\n}\n\nfunction parse_css_int(str) { // int or percentage.\n if (str[str.length - 1] === '%')\n return clamp_css_byte(parseFloat(str) / 100 * 255);\n return clamp_css_byte(parseInt(str));\n}\n\nfunction parse_css_float(str) { // float or percentage.\n if (str[str.length - 1] === '%')\n return clamp_css_float(parseFloat(str) / 100);\n return clamp_css_float(parseFloat(str));\n}\n\nfunction css_hue_to_rgb(m1, m2, h) {\n if (h < 0) h += 1;\n else if (h > 1) h -= 1;\n\n if (h * 6 < 1) return m1 + (m2 - m1) * h * 6;\n if (h * 2 < 1) return m2;\n if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;\n return m1;\n}\n\nfunction parseCSSColor(css_str) {\n // Remove all whitespace, not compliant, but should just be more accepting.\n var str = css_str.replace(/ /g, '').toLowerCase();\n\n // Color keywords (and transparent) lookup.\n if (str in kCSSColorTable) return kCSSColorTable[str].slice(); // dup.\n\n // #abc and #abc123 syntax.\n if (str[0] === '#') {\n if (str.length === 4) {\n var iv = parseInt(str.substr(1), 16); // TODO(deanm): Stricter parsing.\n if (!(iv >= 0 && iv <= 0xfff)) return null; // Covers NaN.\n return [((iv & 0xf00) >> 4) | ((iv & 0xf00) >> 8),\n (iv & 0xf0) | ((iv & 0xf0) >> 4),\n (iv & 0xf) | ((iv & 0xf) << 4),\n 1];\n } else if (str.length === 7) {\n var iv = parseInt(str.substr(1), 16); // TODO(deanm): Stricter parsing.\n if (!(iv >= 0 && iv <= 0xffffff)) return null; // Covers NaN.\n return [(iv & 0xff0000) >> 16,\n (iv & 0xff00) >> 8,\n iv & 0xff,\n 1];\n }\n\n return null;\n }\n\n var op = str.indexOf('('), ep = str.indexOf(')');\n if (op !== -1 && ep + 1 === str.length) {\n var fname = str.substr(0, op);\n var params = str.substr(op+1, ep-(op+1)).split(',');\n var alpha = 1; // To allow case fallthrough.\n switch (fname) {\n case 'rgba':\n if (params.length !== 4) return null;\n alpha = parse_css_float(params.pop());\n // Fall through.\n case 'rgb':\n if (params.length !== 3) return null;\n return [parse_css_int(params[0]),\n parse_css_int(params[1]),\n parse_css_int(params[2]),\n alpha];\n case 'hsla':\n if (params.length !== 4) return null;\n alpha = parse_css_float(params.pop());\n // Fall through.\n case 'hsl':\n if (params.length !== 3) return null;\n var h = (((parseFloat(params[0]) % 360) + 360) % 360) / 360; // 0 .. 1\n // NOTE(deanm): According to the CSS spec s/l should only be\n // percentages, but we don't bother and let float or percentage.\n var s = parse_css_float(params[1]);\n var l = parse_css_float(params[2]);\n var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;\n var m1 = l * 2 - m2;\n return [clamp_css_byte(css_hue_to_rgb(m1, m2, h+1/3) * 255),\n clamp_css_byte(css_hue_to_rgb(m1, m2, h) * 255),\n clamp_css_byte(css_hue_to_rgb(m1, m2, h-1/3) * 255),\n alpha];\n default:\n return null;\n }\n }\n\n return null;\n}\n\ntry { exports.parseCSSColor = parseCSSColor } catch(e) { }\n",
"type": "application/javascript",
"module-type": "utils"
},
"$:/core/modules/utils/dom.js": {
"title": "$:/core/modules/utils/dom.js",
"text": "/*\\\ntitle: $:/core/modules/utils/dom.js\ntype: application/javascript\nmodule-type: utils\n\nVarious static DOM-related utility functions.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nDetermines whether element 'a' contains element 'b'\nCode thanks to John Resig, http://ejohn.org/blog/comparing-document-position/\n*/\nexports.domContains = function(a,b) {\n\treturn a.contains ?\n\t\ta !== b && a.contains(b) :\n\t\t!!(a.compareDocumentPosition(b) & 16);\n};\n\nexports.removeChildren = function(node) {\n\twhile(node.hasChildNodes()) {\n\t\tnode.removeChild(node.firstChild);\n\t}\n};\n\nexports.hasClass = function(el,className) {\n\treturn el && el.className && el.className.toString().split(\" \").indexOf(className) !== -1;\n};\n\nexports.addClass = function(el,className) {\n\tvar c = el.className.split(\" \");\n\tif(c.indexOf(className) === -1) {\n\t\tc.push(className);\n\t}\n\tel.className = c.join(\" \");\n};\n\nexports.removeClass = function(el,className) {\n\tvar c = el.className.split(\" \"),\n\t\tp = c.indexOf(className);\n\tif(p !== -1) {\n\t\tc.splice(p,1);\n\t\tel.className = c.join(\" \");\n\t}\n};\n\nexports.toggleClass = function(el,className,status) {\n\tif(status === undefined) {\n\t\tstatus = !exports.hasClass(el,className);\n\t}\n\tif(status) {\n\t\texports.addClass(el,className);\n\t} else {\n\t\texports.removeClass(el,className);\n\t}\n};\n\n/*\nGet the first parent element that has scrollbars or use the body as fallback.\n*/\nexports.getScrollContainer = function(el) {\n\tvar doc = el.ownerDocument;\n\twhile(el.parentNode) {\t\n\t\tel = el.parentNode;\n\t\tif(el.scrollTop) {\n\t\t\treturn el;\n\t\t}\n\t}\n\treturn doc.body;\n};\n\n/*\nGet the scroll position of the viewport\nReturns:\n\t{\n\t\tx: horizontal scroll position in pixels,\n\t\ty: vertical scroll position in pixels\n\t}\n*/\nexports.getScrollPosition = function(srcWindow) {\n\tvar scrollWindow = srcWindow || window;\n\tif(\"scrollX\" in scrollWindow) {\n\t\treturn {x: scrollWindow.scrollX, y: scrollWindow.scrollY};\n\t} else {\n\t\treturn {x: scrollWindow.document.documentElement.scrollLeft, y: scrollWindow.document.documentElement.scrollTop};\n\t}\n};\n\n/*\nAdjust the height of a textarea to fit its content, preserving scroll position, and return the height\n*/\nexports.resizeTextAreaToFit = function(domNode,minHeight) {\n\t// Get the scroll container and register the current scroll position\n\tvar container = $tw.utils.getScrollContainer(domNode),\n\t\tscrollTop = container.scrollTop;\n // Measure the specified minimum height\n\tdomNode.style.height = minHeight;\n\tvar measuredHeight = domNode.offsetHeight || parseInt(minHeight,10);\n\t// Set its height to auto so that it snaps to the correct height\n\tdomNode.style.height = \"auto\";\n\t// Calculate the revised height\n\tvar newHeight = Math.max(domNode.scrollHeight + domNode.offsetHeight - domNode.clientHeight,measuredHeight);\n\t// Only try to change the height if it has changed\n\tif(newHeight !== domNode.offsetHeight) {\n\t\tdomNode.style.height = newHeight + \"px\";\n\t\t// Make sure that the dimensions of the textarea are recalculated\n\t\t$tw.utils.forceLayout(domNode);\n\t\t// Set the container to the position we registered at the beginning\n\t\tcontainer.scrollTop = scrollTop;\n\t}\n\treturn newHeight;\n};\n\n/*\nGets the bounding rectangle of an element in absolute page coordinates\n*/\nexports.getBoundingPageRect = function(element) {\n\tvar scrollPos = $tw.utils.getScrollPosition(element.ownerDocument.defaultView),\n\t\tclientRect = element.getBoundingClientRect();\n\treturn {\n\t\tleft: clientRect.left + scrollPos.x,\n\t\twidth: clientRect.width,\n\t\tright: clientRect.right + scrollPos.x,\n\t\ttop: clientRect.top + scrollPos.y,\n\t\theight: clientRect.height,\n\t\tbottom: clientRect.bottom + scrollPos.y\n\t};\n};\n\n/*\nSaves a named password in the browser\n*/\nexports.savePassword = function(name,password) {\n\ttry {\n\t\tif(window.localStorage) {\n\t\t\tlocalStorage.setItem(\"tw5-password-\" + name,password);\n\t\t}\n\t} catch(e) {\n\t}\n};\n\n/*\nRetrieve a named password from the browser\n*/\nexports.getPassword = function(name) {\n\ttry {\n\t\treturn window.localStorage ? localStorage.getItem(\"tw5-password-\" + name) : \"\";\n\t} catch(e) {\n\t\treturn \"\";\n\t}\n};\n\n/*\nForce layout of a dom node and its descendents\n*/\nexports.forceLayout = function(element) {\n\tvar dummy = element.offsetWidth;\n};\n\n/*\nPulse an element for debugging purposes\n*/\nexports.pulseElement = function(element) {\n\t// Event handler to remove the class at the end\n\telement.addEventListener($tw.browser.animationEnd,function handler(event) {\n\t\telement.removeEventListener($tw.browser.animationEnd,handler,false);\n\t\t$tw.utils.removeClass(element,\"pulse\");\n\t},false);\n\t// Apply the pulse class\n\t$tw.utils.removeClass(element,\"pulse\");\n\t$tw.utils.forceLayout(element);\n\t$tw.utils.addClass(element,\"pulse\");\n};\n\n/*\nAttach specified event handlers to a DOM node\ndomNode: where to attach the event handlers\nevents: array of event handlers to be added (see below)\nEach entry in the events array is an object with these properties:\nhandlerFunction: optional event handler function\nhandlerObject: optional event handler object\nhandlerMethod: optionally specifies object handler method name (defaults to `handleEvent`)\n*/\nexports.addEventListeners = function(domNode,events) {\n\t$tw.utils.each(events,function(eventInfo) {\n\t\tvar handler;\n\t\tif(eventInfo.handlerFunction) {\n\t\t\thandler = eventInfo.handlerFunction;\n\t\t} else if(eventInfo.handlerObject) {\n\t\t\tif(eventInfo.handlerMethod) {\n\t\t\t\thandler = function(event) {\n\t\t\t\t\teventInfo.handlerObject[eventInfo.handlerMethod].call(eventInfo.handlerObject,event);\n\t\t\t\t};\t\n\t\t\t} else {\n\t\t\t\thandler = eventInfo.handlerObject;\n\t\t\t}\n\t\t}\n\t\tdomNode.addEventListener(eventInfo.name,handler,false);\n\t});\n};\n\n/*\nGet the computed styles applied to an element as an array of strings of individual CSS properties\n*/\nexports.getComputedStyles = function(domNode) {\n\tvar textAreaStyles = window.getComputedStyle(domNode,null),\n\t\tstyleDefs = [],\n\t\tname;\n\tfor(var t=0; t<textAreaStyles.length; t++) {\n\t\tname = textAreaStyles[t];\n\t\tstyleDefs.push(name + \": \" + textAreaStyles.getPropertyValue(name) + \";\");\n\t}\n\treturn styleDefs;\n};\n\n/*\nApply a set of styles passed as an array of strings of individual CSS properties\n*/\nexports.setStyles = function(domNode,styleDefs) {\n\tdomNode.style.cssText = styleDefs.join(\"\");\n};\n\n/*\nCopy the computed styles from a source element to a destination element\n*/\nexports.copyStyles = function(srcDomNode,dstDomNode) {\n\t$tw.utils.setStyles(dstDomNode,$tw.utils.getComputedStyles(srcDomNode));\n};\n\n/*\nCopy plain text to the clipboard on browsers that support it\n*/\nexports.copyToClipboard = function(text,options) {\n\toptions = options || {};\n\tvar textArea = document.createElement(\"textarea\");\n\ttextArea.style.position = \"fixed\";\n\ttextArea.style.top = 0;\n\ttextArea.style.left = 0;\n\ttextArea.style.fontSize = \"12pt\";\n\ttextArea.style.width = \"2em\";\n\ttextArea.style.height = \"2em\";\n\ttextArea.style.padding = 0;\n\ttextArea.style.border = \"none\";\n\ttextArea.style.outline = \"none\";\n\ttextArea.style.boxShadow = \"none\";\n\ttextArea.style.background = \"transparent\";\n\ttextArea.value = text;\n\tdocument.body.appendChild(textArea);\n\ttextArea.select();\n\ttextArea.setSelectionRange(0,text.length);\n\tvar succeeded = false;\n\ttry {\n\t\tsucceeded = document.execCommand(\"copy\");\n\t} catch (err) {\n\t}\n\tif(!options.doNotNotify) {\n\t\t$tw.notifier.display(succeeded ? \"$:/language/Notifications/CopiedToClipboard/Succeeded\" : \"$:/language/Notifications/CopiedToClipboard/Failed\");\n\t}\n\tdocument.body.removeChild(textArea);\n};\n\nexports.getLocationPath = function() {\n\treturn window.location.toString().split(\"#\")[0];\n};\n\n\n})();\n",
"type": "application/javascript",
"module-type": "utils"
},
"$:/core/modules/utils/dom/dragndrop.js": {
"title": "$:/core/modules/utils/dom/dragndrop.js",
"text": "/*\\\ntitle: $:/core/modules/utils/dom/dragndrop.js\ntype: application/javascript\nmodule-type: utils\n\nBrowser data transfer utilities, used with the clipboard and drag and drop\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nOptions:\n\ndomNode: dom node to make draggable\ndragImageType: \"pill\" or \"dom\"\ndragTiddlerFn: optional function to retrieve the title of tiddler to drag\ndragFilterFn: optional function to retreive the filter defining a list of tiddlers to drag\nwidget: widget to use as the contect for the filter\n*/\nexports.makeDraggable = function(options) {\n\tvar dragImageType = options.dragImageType || \"dom\",\n\t\tdragImage,\n\t\tdomNode = options.domNode;\n\t// Make the dom node draggable (not necessary for anchor tags)\n\tif((domNode.tagName || \"\").toLowerCase() !== \"a\") {\n\t\tdomNode.setAttribute(\"draggable\",\"true\");\t\t\n\t}\n\t// Add event handlers\n\t$tw.utils.addEventListeners(domNode,[\n\t\t{name: \"dragstart\", handlerFunction: function(event) {\n\t\t\tif(event.dataTransfer === undefined) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\t// Collect the tiddlers being dragged\n\t\t\tvar dragTiddler = options.dragTiddlerFn && options.dragTiddlerFn(),\n\t\t\t\tdragFilter = options.dragFilterFn && options.dragFilterFn(),\n\t\t\t\ttitles = dragTiddler ? [dragTiddler] : [],\n\t\t\t \tstartActions = options.startActions;\n\t\t\tif(dragFilter) {\n\t\t\t\ttitles.push.apply(titles,options.widget.wiki.filterTiddlers(dragFilter,options.widget));\n\t\t\t}\n\t\t\tvar titleString = $tw.utils.stringifyList(titles);\n\t\t\t// Check that we've something to drag\n\t\t\tif(titles.length > 0 && event.target === domNode) {\n\t\t\t\t// Mark the drag in progress\n\t\t\t\t$tw.dragInProgress = domNode;\n\t\t\t\t// Set the dragging class on the element being dragged\n\t\t\t\t$tw.utils.addClass(event.target,\"tc-dragging\");\n\t\t\t\t// Invoke drag-start actions if given\n\t\t\t\tif(startActions !== undefined) {\n\t\t\t\t\toptions.widget.invokeActionString(startActions,options.widget,event,{actionTiddler: titleString});\n\t\t\t\t}\n\t\t\t\t// Create the drag image elements\n\t\t\t\tdragImage = options.widget.document.createElement(\"div\");\n\t\t\t\tdragImage.className = \"tc-tiddler-dragger\";\n\t\t\t\tvar inner = options.widget.document.createElement(\"div\");\n\t\t\t\tinner.className = \"tc-tiddler-dragger-inner\";\n\t\t\t\tinner.appendChild(options.widget.document.createTextNode(\n\t\t\t\t\ttitles.length === 1 ? \n\t\t\t\t\t\ttitles[0] :\n\t\t\t\t\t\ttitles.length + \" tiddlers\"\n\t\t\t\t));\n\t\t\t\tdragImage.appendChild(inner);\n\t\t\t\toptions.widget.document.body.appendChild(dragImage);\n\t\t\t\t// Set the data transfer properties\n\t\t\t\tvar dataTransfer = event.dataTransfer;\n\t\t\t\t// Set up the image\n\t\t\t\tdataTransfer.effectAllowed = \"all\";\n\t\t\t\tif(dataTransfer.setDragImage) {\n\t\t\t\t\tif(dragImageType === \"pill\") {\n\t\t\t\t\t\tdataTransfer.setDragImage(dragImage.firstChild,-16,-16);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tvar r = domNode.getBoundingClientRect();\n\t\t\t\t\t\tdataTransfer.setDragImage(domNode,event.clientX-r.left,event.clientY-r.top);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Set up the data transfer\n\t\t\t\tif(dataTransfer.clearData) {\n\t\t\t\t\tdataTransfer.clearData();\t\t\t\t\t\n\t\t\t\t}\n\t\t\t\tvar jsonData = [];\n\t\t\t\tif(titles.length > 1) {\n\t\t\t\t\ttitles.forEach(function(title) {\n\t\t\t\t\t\tjsonData.push(options.widget.wiki.getTiddlerAsJson(title));\n\t\t\t\t\t});\n\t\t\t\t\tjsonData = \"[\" + jsonData.join(\",\") + \"]\";\n\t\t\t\t} else {\n\t\t\t\t\tjsonData = options.widget.wiki.getTiddlerAsJson(titles[0]);\n\t\t\t\t}\n\t\t\t\t// IE doesn't like these content types\n\t\t\t\tif(!$tw.browser.isIE) {\n\t\t\t\t\tdataTransfer.setData(\"text/vnd.tiddler\",jsonData);\n\t\t\t\t\tdataTransfer.setData(\"text/plain\",titleString);\n\t\t\t\t\tdataTransfer.setData(\"text/x-moz-url\",\"data:text/vnd.tiddler,\" + encodeURIComponent(jsonData));\n\t\t\t\t}\n\t\t\t\tdataTransfer.setData(\"URL\",\"data:text/vnd.tiddler,\" + encodeURIComponent(jsonData));\n\t\t\t\tdataTransfer.setData(\"Text\",titleString);\n\t\t\t\tevent.stopPropagation();\n\t\t\t}\n\t\t\treturn false;\n\t\t}},\n\t\t{name: \"dragend\", handlerFunction: function(event) {\n\t\t\tif(event.target === domNode) {\n\t\t\t\t// Collect the tiddlers being dragged\n\t\t\t\tvar dragTiddler = options.dragTiddlerFn && options.dragTiddlerFn(),\n\t\t\t\t\tdragFilter = options.dragFilterFn && options.dragFilterFn(),\n\t\t\t\t\ttitles = dragTiddler ? [dragTiddler] : [],\n\t\t\t \t\tendActions = options.endActions;\n\t\t\t\tif(dragFilter) {\n\t\t\t\t\ttitles.push.apply(titles,options.widget.wiki.filterTiddlers(dragFilter,options.widget));\n\t\t\t\t}\n\t\t\t\tvar titleString = $tw.utils.stringifyList(titles);\n\t\t\t\t$tw.dragInProgress = null;\n\t\t\t\t// Invoke drag-end actions if given\n\t\t\t\tif(endActions !== undefined) {\n\t\t\t\t\toptions.widget.invokeActionString(endActions,options.widget,event,{actionTiddler: titleString});\n\t\t\t\t}\n\t\t\t\t// Remove the dragging class on the element being dragged\n\t\t\t\t$tw.utils.removeClass(event.target,\"tc-dragging\");\n\t\t\t\t// Delete the drag image element\n\t\t\t\tif(dragImage) {\n\t\t\t\t\tdragImage.parentNode.removeChild(dragImage);\n\t\t\t\t\tdragImage = null;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}}\n\t]);\n};\n\nexports.importDataTransfer = function(dataTransfer,fallbackTitle,callback) {\n\t// Try each provided data type in turn\n\tif($tw.log.IMPORT) {\n\t\tconsole.log(\"Available data types:\");\n\t\tfor(var type=0; type<dataTransfer.types.length; type++) {\n\t\t\tconsole.log(\"type\",dataTransfer.types[type],dataTransfer.getData(dataTransfer.types[type]))\n\t\t}\n\t}\n\tfor(var t=0; t<importDataTypes.length; t++) {\n\t\tif(!$tw.browser.isIE || importDataTypes[t].IECompatible) {\n\t\t\t// Get the data\n\t\t\tvar dataType = importDataTypes[t];\n\t\t\t\tvar data = dataTransfer.getData(dataType.type);\n\t\t\t// Import the tiddlers in the data\n\t\t\tif(data !== \"\" && data !== null) {\n\t\t\t\tif($tw.log.IMPORT) {\n\t\t\t\t\tconsole.log(\"Importing data type '\" + dataType.type + \"', data: '\" + data + \"'\")\n\t\t\t\t}\n\t\t\t\tvar tiddlerFields = dataType.toTiddlerFieldsArray(data,fallbackTitle);\n\t\t\t\tcallback(tiddlerFields);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n};\n\nvar importDataTypes = [\n\t{type: \"text/vnd.tiddler\", IECompatible: false, toTiddlerFieldsArray: function(data,fallbackTitle) {\n\t\treturn parseJSONTiddlers(data,fallbackTitle);\n\t}},\n\t{type: \"URL\", IECompatible: true, toTiddlerFieldsArray: function(data,fallbackTitle) {\n\t\t// Check for tiddler data URI\n\t\tvar match = decodeURIComponent(data).match(/^data\\:text\\/vnd\\.tiddler,(.*)/i);\n\t\tif(match) {\n\t\t\treturn parseJSONTiddlers(match[1],fallbackTitle);\n\t\t} else {\n\t\t\treturn [{title: fallbackTitle, text: data}]; // As URL string\n\t\t}\n\t}},\n\t{type: \"text/x-moz-url\", IECompatible: false, toTiddlerFieldsArray: function(data,fallbackTitle) {\n\t\t// Check for tiddler data URI\n\t\tvar match = decodeURIComponent(data).match(/^data\\:text\\/vnd\\.tiddler,(.*)/i);\n\t\tif(match) {\n\t\t\treturn parseJSONTiddlers(match[1],fallbackTitle);\n\t\t} else {\n\t\t\treturn [{title: fallbackTitle, text: data}]; // As URL string\n\t\t}\n\t}},\n\t{type: \"text/html\", IECompatible: false, toTiddlerFieldsArray: function(data,fallbackTitle) {\n\t\treturn [{title: fallbackTitle, text: data}];\n\t}},\n\t{type: \"text/plain\", IECompatible: false, toTiddlerFieldsArray: function(data,fallbackTitle) {\n\t\treturn [{title: fallbackTitle, text: data}];\n\t}},\n\t{type: \"Text\", IECompatible: true, toTiddlerFieldsArray: function(data,fallbackTitle) {\n\t\treturn [{title: fallbackTitle, text: data}];\n\t}},\n\t{type: \"text/uri-list\", IECompatible: false, toTiddlerFieldsArray: function(data,fallbackTitle) {\n\t\treturn [{title: fallbackTitle, text: data}];\n\t}}\n];\n\nfunction parseJSONTiddlers(json,fallbackTitle) {\n\tvar data = JSON.parse(json);\n\tif(!$tw.utils.isArray(data)) {\n\t\tdata = [data];\n\t}\n\tdata.forEach(function(fields) {\n\t\tfields.title = fields.title || fallbackTitle;\n\t});\n\treturn data;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "utils"
},
"$:/core/modules/utils/dom/http.js": {
"title": "$:/core/modules/utils/dom/http.js",
"text": "/*\\\ntitle: $:/core/modules/utils/dom/http.js\ntype: application/javascript\nmodule-type: utils\n\nBrowser HTTP support\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nA quick and dirty HTTP function; to be refactored later. Options are:\n\turl: URL to retrieve\n\theaders: hashmap of headers to send\n\ttype: GET, PUT, POST etc\n\tcallback: function invoked with (err,data)\n\treturnProp: string name of the property to return as first argument of callback\n*/\nexports.httpRequest = function(options) {\n\tvar type = options.type || \"GET\",\n\t\theaders = options.headers || {accept: \"application/json\"},\n\t\treturnProp = options.returnProp || \"responseText\",\n\t\trequest = new XMLHttpRequest(),\n\t\tdata = \"\",\n\t\tf,results;\n\t// Massage the data hashmap into a string\n\tif(options.data) {\n\t\tif(typeof options.data === \"string\") { // Already a string\n\t\t\tdata = options.data;\n\t\t} else { // A hashmap of strings\n\t\t\tresults = [];\n\t\t\t$tw.utils.each(options.data,function(dataItem,dataItemTitle) {\n\t\t\t\tresults.push(dataItemTitle + \"=\" + encodeURIComponent(dataItem));\n\t\t\t});\n\t\t\tdata = results.join(\"&\");\n\t\t}\n\t}\n\t// Set up the state change handler\n\trequest.onreadystatechange = function() {\n\t\tif(this.readyState === 4) {\n\t\t\tif(this.status === 200 || this.status === 201 || this.status === 204) {\n\t\t\t\t// Success!\n\t\t\t\toptions.callback(null,this[returnProp],this);\n\t\t\t\treturn;\n\t\t\t}\n\t\t// Something went wrong\n\t\toptions.callback($tw.language.getString(\"Error/XMLHttpRequest\") + \": \" + this.status);\n\t\t}\n\t};\n\t// Make the request\n\trequest.open(type,options.url,true);\n\tif(headers) {\n\t\t$tw.utils.each(headers,function(header,headerTitle,object) {\n\t\t\trequest.setRequestHeader(headerTitle,header);\n\t\t});\n\t}\n\tif(data && !$tw.utils.hop(headers,\"Content-type\")) {\n\t\trequest.setRequestHeader(\"Content-type\",\"application/x-www-form-urlencoded; charset=UTF-8\");\n\t}\n\tif(!$tw.utils.hop(headers,\"X-Requested-With\")) {\n\t\trequest.setRequestHeader(\"X-Requested-With\",\"TiddlyWiki\");\n\t}\n\ttry {\n\t\trequest.send(data);\n\t} catch(e) {\n\t\toptions.callback(e);\n\t}\n\treturn request;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "utils"
},
"$:/core/modules/utils/dom/keyboard.js": {
"title": "$:/core/modules/utils/dom/keyboard.js",
"text": "/*\\\ntitle: $:/core/modules/utils/dom/keyboard.js\ntype: application/javascript\nmodule-type: utils\n\nKeyboard utilities; now deprecated. Instead, use $tw.keyboardManager\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n[\"parseKeyDescriptor\",\"checkKeyDescriptor\"].forEach(function(method) {\n\texports[method] = function() {\n\t\tif($tw.keyboardManager) {\n\t\t\treturn $tw.keyboardManager[method].apply($tw.keyboardManager,Array.prototype.slice.call(arguments,0));\n\t\t} else {\n\t\t\treturn null\n\t\t}\n\t};\n});\n\n})();\n",
"type": "application/javascript",
"module-type": "utils"
},
"$:/core/modules/utils/dom/modal.js": {
"title": "$:/core/modules/utils/dom/modal.js",
"text": "/*\\\ntitle: $:/core/modules/utils/dom/modal.js\ntype: application/javascript\nmodule-type: utils\n\nModal message mechanism\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar widget = require(\"$:/core/modules/widgets/widget.js\");\n\nvar Modal = function(wiki) {\n\tthis.wiki = wiki;\n\tthis.modalCount = 0;\n};\n\n/*\nDisplay a modal dialogue\n\ttitle: Title of tiddler to display\n\toptions: see below\nOptions include:\n\tdownloadLink: Text of a big download link to include\n*/\nModal.prototype.display = function(title,options) {\n\toptions = options || {};\n\tthis.srcDocument = options.variables && (options.variables.rootwindow === \"true\" ||\n\t\t\t\toptions.variables.rootwindow === \"yes\") ? document :\n\t\t\t\t(options.event.event ? options.event.event.target.ownerDocument : document);\n\tthis.srcWindow = this.srcDocument.defaultView;\n\tvar self = this,\n\t\trefreshHandler,\n\t\tduration = $tw.utils.getAnimationDuration(),\n\t\ttiddler = this.wiki.getTiddler(title);\n\t// Don't do anything if the tiddler doesn't exist\n\tif(!tiddler) {\n\t\treturn;\n\t}\n\t// Create the variables\n\tvar variables = $tw.utils.extend({currentTiddler: title},options.variables);\n\t// Create the wrapper divs\n\tvar wrapper = this.srcDocument.createElement(\"div\"),\n\t\tmodalBackdrop = this.srcDocument.createElement(\"div\"),\n\t\tmodalWrapper = this.srcDocument.createElement(\"div\"),\n\t\tmodalHeader = this.srcDocument.createElement(\"div\"),\n\t\theaderTitle = this.srcDocument.createElement(\"h3\"),\n\t\tmodalBody = this.srcDocument.createElement(\"div\"),\n\t\tmodalLink = this.srcDocument.createElement(\"a\"),\n\t\tmodalFooter = this.srcDocument.createElement(\"div\"),\n\t\tmodalFooterHelp = this.srcDocument.createElement(\"span\"),\n\t\tmodalFooterButtons = this.srcDocument.createElement(\"span\");\n\t// Up the modal count and adjust the body class\n\tthis.modalCount++;\n\tthis.adjustPageClass();\n\t// Add classes\n\t$tw.utils.addClass(wrapper,\"tc-modal-wrapper\");\n\t$tw.utils.addClass(modalBackdrop,\"tc-modal-backdrop\");\n\t$tw.utils.addClass(modalWrapper,\"tc-modal\");\n\t$tw.utils.addClass(modalHeader,\"tc-modal-header\");\n\t$tw.utils.addClass(modalBody,\"tc-modal-body\");\n\t$tw.utils.addClass(modalFooter,\"tc-modal-footer\");\n\t// Join them together\n\twrapper.appendChild(modalBackdrop);\n\twrapper.appendChild(modalWrapper);\n\tmodalHeader.appendChild(headerTitle);\n\tmodalWrapper.appendChild(modalHeader);\n\tmodalWrapper.appendChild(modalBody);\n\tmodalFooter.appendChild(modalFooterHelp);\n\tmodalFooter.appendChild(modalFooterButtons);\n\tmodalWrapper.appendChild(modalFooter);\n\t// Render the title of the message\n\tvar headerWidgetNode = this.wiki.makeTranscludeWidget(title,{\n\t\tfield: \"subtitle\",\n\t\tmode: \"inline\",\n\t\tchildren: [{\n\t\t\ttype: \"text\",\n\t\t\tattributes: {\n\t\t\t\ttext: {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tvalue: title\n\t\t}}}],\n\t\tparentWidget: $tw.rootWidget,\n\t\tdocument: this.srcDocument,\n\t\tvariables: variables,\n\t\timportPageMacros: true\n\t});\n\theaderWidgetNode.render(headerTitle,null);\n\t// Render the body of the message\n\tvar bodyWidgetNode = this.wiki.makeTranscludeWidget(title,{\n\t\tparentWidget: $tw.rootWidget,\n\t\tdocument: this.srcDocument,\n\t\tvariables: variables,\n\t\timportPageMacros: true\n\t});\n\tbodyWidgetNode.render(modalBody,null);\n\t// Setup the link if present\n\tif(options.downloadLink) {\n\t\tmodalLink.href = options.downloadLink;\n\t\tmodalLink.appendChild(this.srcDocument.createTextNode(\"Right-click to save changes\"));\n\t\tmodalBody.appendChild(modalLink);\n\t}\n\t// Render the footer of the message\n\tif(tiddler && tiddler.fields && tiddler.fields.help) {\n\t\tvar link = this.srcDocument.createElement(\"a\");\n\t\tlink.setAttribute(\"href\",tiddler.fields.help);\n\t\tlink.setAttribute(\"target\",\"_blank\");\n\t\tlink.setAttribute(\"rel\",\"noopener noreferrer\");\n\t\tlink.appendChild(this.srcDocument.createTextNode(\"Help\"));\n\t\tmodalFooterHelp.appendChild(link);\n\t\tmodalFooterHelp.style.float = \"left\";\n\t}\n\tvar footerWidgetNode = this.wiki.makeTranscludeWidget(title,{\n\t\tfield: \"footer\",\n\t\tmode: \"inline\",\n\t\tchildren: [{\n\t\t\ttype: \"button\",\n\t\t\tattributes: {\n\t\t\t\tmessage: {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tvalue: \"tm-close-tiddler\"\n\t\t\t\t}\n\t\t\t},\n\t\t\tchildren: [{\n\t\t\t\ttype: \"text\",\n\t\t\t\tattributes: {\n\t\t\t\t\ttext: {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tvalue: $tw.language.getString(\"Buttons/Close/Caption\")\n\t\t\t}}}\n\t\t]}],\n\t\tparentWidget: $tw.rootWidget,\n\t\tdocument: this.srcDocument,\n\t\tvariables: variables,\n\t\timportPageMacros: true\n\t});\n\tfooterWidgetNode.render(modalFooterButtons,null);\n\t// Set up the refresh handler\n\trefreshHandler = function(changes) {\n\t\theaderWidgetNode.refresh(changes,modalHeader,null);\n\t\tbodyWidgetNode.refresh(changes,modalBody,null);\n\t\tfooterWidgetNode.refresh(changes,modalFooterButtons,null);\n\t};\n\tthis.wiki.addEventListener(\"change\",refreshHandler);\n\t// Add the close event handler\n\tvar closeHandler = function(event) {\n\t\t// Remove our refresh handler\n\t\tself.wiki.removeEventListener(\"change\",refreshHandler);\n\t\t// Decrease the modal count and adjust the body class\n\t\tself.modalCount--;\n\t\tself.adjustPageClass();\n\t\t// Force layout and animate the modal message away\n\t\t$tw.utils.forceLayout(modalBackdrop);\n\t\t$tw.utils.forceLayout(modalWrapper);\n\t\t$tw.utils.setStyle(modalBackdrop,[\n\t\t\t{opacity: \"0\"}\n\t\t]);\n\t\t$tw.utils.setStyle(modalWrapper,[\n\t\t\t{transform: \"translateY(\" + self.srcWindow.innerHeight + \"px)\"}\n\t\t]);\n\t\t// Set up an event for the transition end\n\t\tself.srcWindow.setTimeout(function() {\n\t\t\tif(wrapper.parentNode) {\n\t\t\t\t// Remove the modal message from the DOM\n\t\t\t\tself.srcDocument.body.removeChild(wrapper);\n\t\t\t}\n\t\t},duration);\n\t\t// Don't let anyone else handle the tm-close-tiddler message\n\t\treturn false;\n\t};\n\theaderWidgetNode.addEventListener(\"tm-close-tiddler\",closeHandler,false);\n\tbodyWidgetNode.addEventListener(\"tm-close-tiddler\",closeHandler,false);\n\tfooterWidgetNode.addEventListener(\"tm-close-tiddler\",closeHandler,false);\n\t// Set the initial styles for the message\n\t$tw.utils.setStyle(modalBackdrop,[\n\t\t{opacity: \"0\"}\n\t]);\n\t$tw.utils.setStyle(modalWrapper,[\n\t\t{transformOrigin: \"0% 0%\"},\n\t\t{transform: \"translateY(\" + (-this.srcWindow.innerHeight) + \"px)\"}\n\t]);\n\t// Put the message into the document\n\tthis.srcDocument.body.appendChild(wrapper);\n\t// Set up animation for the styles\n\t$tw.utils.setStyle(modalBackdrop,[\n\t\t{transition: \"opacity \" + duration + \"ms ease-out\"}\n\t]);\n\t$tw.utils.setStyle(modalWrapper,[\n\t\t{transition: $tw.utils.roundTripPropertyName(\"transform\") + \" \" + duration + \"ms ease-in-out\"}\n\t]);\n\t// Force layout\n\t$tw.utils.forceLayout(modalBackdrop);\n\t$tw.utils.forceLayout(modalWrapper);\n\t// Set final animated styles\n\t$tw.utils.setStyle(modalBackdrop,[\n\t\t{opacity: \"0.7\"}\n\t]);\n\t$tw.utils.setStyle(modalWrapper,[\n\t\t{transform: \"translateY(0px)\"}\n\t]);\n};\n\nModal.prototype.adjustPageClass = function() {\n\tvar windowContainer = $tw.pageContainer ? ($tw.pageContainer === this.srcDocument.body.firstChild ? $tw.pageContainer : this.srcDocument.body.firstChild) : null;\n\tif(windowContainer) {\n\t\t$tw.utils.toggleClass(windowContainer,\"tc-modal-displayed\",this.modalCount > 0);\n\t}\n};\n\nexports.Modal = Modal;\n\n})();\n",
"type": "application/javascript",
"module-type": "utils"
},
"$:/core/modules/utils/dom/notifier.js": {
"title": "$:/core/modules/utils/dom/notifier.js",
"text": "/*\\\ntitle: $:/core/modules/utils/dom/notifier.js\ntype: application/javascript\nmodule-type: utils\n\nNotifier mechanism\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar widget = require(\"$:/core/modules/widgets/widget.js\");\n\nvar Notifier = function(wiki) {\n\tthis.wiki = wiki;\n};\n\n/*\nDisplay a notification\n\ttitle: Title of tiddler containing the notification text\n\toptions: see below\nOptions include:\n*/\nNotifier.prototype.display = function(title,options) {\n\toptions = options || {};\n\t// Create the wrapper divs\n\tvar self = this,\n\t\tnotification = document.createElement(\"div\"),\n\t\ttiddler = this.wiki.getTiddler(title),\n\t\tduration = $tw.utils.getAnimationDuration(),\n\t\trefreshHandler;\n\t// Don't do anything if the tiddler doesn't exist\n\tif(!tiddler) {\n\t\treturn;\n\t}\n\t// Add classes\n\t$tw.utils.addClass(notification,\"tc-notification\");\n\t// Create the variables\n\tvar variables = $tw.utils.extend({currentTiddler: title},options.variables);\n\t// Render the body of the notification\n\tvar widgetNode = this.wiki.makeTranscludeWidget(title,{\n\t\tparentWidget: $tw.rootWidget,\n\t\tdocument: document,\n\t\tvariables: variables,\n\t\timportPageMacros: true});\n\twidgetNode.render(notification,null);\n\trefreshHandler = function(changes) {\n\t\twidgetNode.refresh(changes,notification,null);\n\t};\n\tthis.wiki.addEventListener(\"change\",refreshHandler);\n\t// Set the initial styles for the notification\n\t$tw.utils.setStyle(notification,[\n\t\t{opacity: \"0\"},\n\t\t{transformOrigin: \"0% 0%\"},\n\t\t{transform: \"translateY(\" + (-window.innerHeight) + \"px)\"},\n\t\t{transition: \"opacity \" + duration + \"ms ease-out, \" + $tw.utils.roundTripPropertyName(\"transform\") + \" \" + duration + \"ms ease-in-out\"}\n\t]);\n\t// Add the notification to the DOM\n\tdocument.body.appendChild(notification);\n\t// Force layout\n\t$tw.utils.forceLayout(notification);\n\t// Set final animated styles\n\t$tw.utils.setStyle(notification,[\n\t\t{opacity: \"1.0\"},\n\t\t{transform: \"translateY(0px)\"}\n\t]);\n\t// Set a timer to remove the notification\n\twindow.setTimeout(function() {\n\t\t// Remove our change event handler\n\t\tself.wiki.removeEventListener(\"change\",refreshHandler);\n\t\t// Force layout and animate the notification away\n\t\t$tw.utils.forceLayout(notification);\n\t\t$tw.utils.setStyle(notification,[\n\t\t\t{opacity: \"0.0\"},\n\t\t\t{transform: \"translateX(\" + (notification.offsetWidth) + \"px)\"}\n\t\t]);\n\t\t// Remove the modal message from the DOM once the transition ends\n\t\tsetTimeout(function() {\n\t\t\tif(notification.parentNode) {\n\t\t\t\tdocument.body.removeChild(notification);\n\t\t\t}\n\t\t},duration);\n\t},$tw.config.preferences.notificationDuration);\n};\n\nexports.Notifier = Notifier;\n\n})();\n",
"type": "application/javascript",
"module-type": "utils"
},
"$:/core/modules/utils/dom/popup.js": {
"title": "$:/core/modules/utils/dom/popup.js",
"text": "/*\\\ntitle: $:/core/modules/utils/dom/popup.js\ntype: application/javascript\nmodule-type: utils\n\nModule that creates a $tw.utils.Popup object prototype that manages popups in the browser\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nCreates a Popup object with these options:\n\trootElement: the DOM element to which the popup zapper should be attached\n*/\nvar Popup = function(options) {\n\toptions = options || {};\n\tthis.rootElement = options.rootElement || document.documentElement;\n\tthis.popups = []; // Array of {title:,wiki:,domNode:} objects\n};\n\n/*\nTrigger a popup open or closed. Parameters are in a hashmap:\n\ttitle: title of the tiddler where the popup details are stored\n\tdomNode: dom node to which the popup will be positioned (one of domNode or domNodeRect is required)\n\tdomNodeRect: rectangle to which the popup will be positioned\n\twiki: wiki\n\tforce: if specified, forces the popup state to true or false (instead of toggling it)\n\tfloating: if true, skips registering the popup, meaning that it will need manually clearing\n*/\nPopup.prototype.triggerPopup = function(options) {\n\t// Check if this popup is already active\n\tvar index = this.findPopup(options.title);\n\t// Compute the new state\n\tvar state = index === -1;\n\tif(options.force !== undefined) {\n\t\tstate = options.force;\n\t}\n\t// Show or cancel the popup according to the new state\n\tif(state) {\n\t\tthis.show(options);\n\t} else {\n\t\tthis.cancel(index);\n\t}\n};\n\nPopup.prototype.findPopup = function(title) {\n\tvar index = -1;\n\tfor(var t=0; t<this.popups.length; t++) {\n\t\tif(this.popups[t].title === title) {\n\t\t\tindex = t;\n\t\t}\n\t}\n\treturn index;\n};\n\nPopup.prototype.handleEvent = function(event) {\n\tif(event.type === \"click\") {\n\t\t// Find out what was clicked on\n\t\tvar info = this.popupInfo(event.target),\n\t\t\tcancelLevel = info.popupLevel - 1;\n\t\t// Don't remove the level that was clicked on if we clicked on a handle\n\t\tif(info.isHandle) {\n\t\t\tcancelLevel++;\n\t\t}\n\t\t// Cancel\n\t\tthis.cancel(cancelLevel);\n\t}\n};\n\n/*\nFind the popup level containing a DOM node. Returns:\npopupLevel: count of the number of nested popups containing the specified element\nisHandle: true if the specified element is within a popup handle\n*/\nPopup.prototype.popupInfo = function(domNode) {\n\tvar isHandle = false,\n\t\tpopupCount = 0,\n\t\tnode = domNode;\n\t// First check ancestors to see if we're within a popup handle\n\twhile(node) {\n\t\tif($tw.utils.hasClass(node,\"tc-popup-handle\")) {\n\t\t\tisHandle = true;\n\t\t\tpopupCount++;\n\t\t}\n\t\tif($tw.utils.hasClass(node,\"tc-popup-keep\")) {\n\t\t\tisHandle = true;\n\t\t}\n\t\tnode = node.parentNode;\n\t}\n\t// Then count the number of ancestor popups\n\tnode = domNode;\n\twhile(node) {\n\t\tif($tw.utils.hasClass(node,\"tc-popup\")) {\n\t\t\tpopupCount++;\n\t\t}\n\t\tnode = node.parentNode;\n\t}\n\tvar info = {\n\t\tpopupLevel: popupCount,\n\t\tisHandle: isHandle\n\t};\n\treturn info;\n};\n\n/*\nDisplay a popup by adding it to the stack\n*/\nPopup.prototype.show = function(options) {\n\t// Find out what was clicked on\n\tvar info = this.popupInfo(options.domNode);\n\t// Cancel any higher level popups\n\tthis.cancel(info.popupLevel);\n\n\t// Store the popup details if not already there\n\tif(!options.floating && this.findPopup(options.title) === -1) {\n\t\tthis.popups.push({\n\t\t\ttitle: options.title,\n\t\t\twiki: options.wiki,\n\t\t\tdomNode: options.domNode\n\t\t});\n\t}\n\t// Set the state tiddler\n\tvar rect;\n\tif(options.domNodeRect) {\n\t\trect = options.domNodeRect;\n\t} else {\n\t\trect = {\n\t\t\tleft: options.domNode.offsetLeft,\n\t\t\ttop: options.domNode.offsetTop,\n\t\t\twidth: options.domNode.offsetWidth,\n\t\t\theight: options.domNode.offsetHeight\n\t\t};\n\t}\n\tvar popupRect = \"(\" + rect.left + \",\" + rect.top + \",\" + \n\t\t\t\trect.width + \",\" + rect.height + \")\";\n\tif(options.noStateReference) {\n\t\toptions.wiki.setText(options.title,\"text\",undefined,popupRect);\n\t} else {\n\t\toptions.wiki.setTextReference(options.title,popupRect);\n\t}\n\t// Add the click handler if we have any popups\n\tif(this.popups.length > 0) {\n\t\tthis.rootElement.addEventListener(\"click\",this,true);\t\t\n\t}\n};\n\n/*\nCancel all popups at or above a specified level or DOM node\nlevel: popup level to cancel (0 cancels all popups)\n*/\nPopup.prototype.cancel = function(level) {\n\tvar numPopups = this.popups.length;\n\tlevel = Math.max(0,Math.min(level,numPopups));\n\tfor(var t=level; t<numPopups; t++) {\n\t\tvar popup = this.popups.pop();\n\t\tif(popup.title) {\n\t\t\tpopup.wiki.deleteTiddler(popup.title);\n\t\t}\n\t}\n\tif(this.popups.length === 0) {\n\t\tthis.rootElement.removeEventListener(\"click\",this,false);\n\t}\n};\n\n/*\nReturns true if the specified title and text identifies an active popup\n*/\nPopup.prototype.readPopupState = function(text) {\n\tvar popupLocationRegExp = /^\\((-?[0-9\\.E]+),(-?[0-9\\.E]+),(-?[0-9\\.E]+),(-?[0-9\\.E]+)\\)$/;\n\treturn popupLocationRegExp.test(text);\n};\n\nexports.Popup = Popup;\n\n})();\n",
"type": "application/javascript",
"module-type": "utils"
},
"$:/core/modules/utils/dom/scroller.js": {
"title": "$:/core/modules/utils/dom/scroller.js",
"text": "/*\\\ntitle: $:/core/modules/utils/dom/scroller.js\ntype: application/javascript\nmodule-type: utils\n\nModule that creates a $tw.utils.Scroller object prototype that manages scrolling in the browser\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nEvent handler for when the `tm-scroll` event hits the document body\n*/\nvar PageScroller = function() {\n\tthis.idRequestFrame = null;\n\tthis.requestAnimationFrame = window.requestAnimationFrame ||\n\t\twindow.webkitRequestAnimationFrame ||\n\t\twindow.mozRequestAnimationFrame ||\n\t\tfunction(callback) {\n\t\t\treturn window.setTimeout(callback, 1000/60);\n\t\t};\n\tthis.cancelAnimationFrame = window.cancelAnimationFrame ||\n\t\twindow.webkitCancelAnimationFrame ||\n\t\twindow.webkitCancelRequestAnimationFrame ||\n\t\twindow.mozCancelAnimationFrame ||\n\t\twindow.mozCancelRequestAnimationFrame ||\n\t\tfunction(id) {\n\t\t\twindow.clearTimeout(id);\n\t\t};\n};\n\nPageScroller.prototype.cancelScroll = function(srcWindow) {\n\tif(this.idRequestFrame) {\n\t\tthis.cancelAnimationFrame.call(srcWindow,this.idRequestFrame);\n\t\tthis.idRequestFrame = null;\n\t}\n};\n\n/*\nHandle an event\n*/\nPageScroller.prototype.handleEvent = function(event) {\n\tif(event.type === \"tm-scroll\") {\n\t\treturn this.scrollIntoView(event.target);\n\t}\n\treturn true;\n};\n\n/*\nHandle a scroll event hitting the page document\n*/\nPageScroller.prototype.scrollIntoView = function(element,callback) {\n\tvar self = this,\n\t\tduration = $tw.utils.getAnimationDuration(),\n\t srcWindow = element ? element.ownerDocument.defaultView : window;\n\t// Now get ready to scroll the body\n\tthis.cancelScroll(srcWindow);\n\tthis.startTime = Date.now();\n\t// Get the height of any position:fixed toolbars\n\tvar toolbar = srcWindow.document.querySelector(\".tc-adjust-top-of-scroll\"),\n\t\toffset = 0;\n\tif(toolbar) {\n\t\toffset = toolbar.offsetHeight;\n\t}\n\t// Get the client bounds of the element and adjust by the scroll position\n\tvar getBounds = function() {\n\t\t\tvar clientBounds = typeof callback === 'function' ? callback() : element.getBoundingClientRect(),\n\t\t\t\tscrollPosition = $tw.utils.getScrollPosition(srcWindow);\n\t\t\treturn {\n\t\t\t\tleft: clientBounds.left + scrollPosition.x,\n\t\t\t\ttop: clientBounds.top + scrollPosition.y - offset,\n\t\t\t\twidth: clientBounds.width,\n\t\t\t\theight: clientBounds.height\n\t\t\t};\n\t\t},\n\t\t// We'll consider the horizontal and vertical scroll directions separately via this function\n\t\t// targetPos/targetSize - position and size of the target element\n\t\t// currentPos/currentSize - position and size of the current scroll viewport\n\t\t// returns: new position of the scroll viewport\n\t\tgetEndPos = function(targetPos,targetSize,currentPos,currentSize) {\n\t\t\tvar newPos = targetPos;\n\t\t\t// If we are scrolling within 50 pixels of the top/left then snap to zero\n\t\t\tif(newPos < 50) {\n\t\t\t\tnewPos = 0;\n\t\t\t}\n\t\t\treturn newPos;\n\t\t},\n\t\tdrawFrame = function drawFrame() {\n\t\t\tvar t;\n\t\t\tif(duration <= 0) {\n\t\t\t\tt = 1;\n\t\t\t} else {\n\t\t\t\tt = ((Date.now()) - self.startTime) / duration;\t\n\t\t\t}\n\t\t\tif(t >= 1) {\n\t\t\t\tself.cancelScroll(srcWindow);\n\t\t\t\tt = 1;\n\t\t\t}\n\t\t\tt = $tw.utils.slowInSlowOut(t);\n\t\t\tvar scrollPosition = $tw.utils.getScrollPosition(srcWindow),\n\t\t\t\tbounds = getBounds(),\n\t\t\t\tendX = getEndPos(bounds.left,bounds.width,scrollPosition.x,srcWindow.innerWidth),\n\t\t\t\tendY = getEndPos(bounds.top,bounds.height,scrollPosition.y,srcWindow.innerHeight);\n\t\t\tsrcWindow.scrollTo(scrollPosition.x + (endX - scrollPosition.x) * t,scrollPosition.y + (endY - scrollPosition.y) * t);\n\t\t\tif(t < 1) {\n\t\t\t\tself.idRequestFrame = self.requestAnimationFrame.call(srcWindow,drawFrame);\n\t\t\t}\n\t\t};\n\tdrawFrame();\n};\n\nexports.PageScroller = PageScroller;\n\n})();\n",
"type": "application/javascript",
"module-type": "utils"
},
"$:/core/modules/utils/edition-info.js": {
"title": "$:/core/modules/utils/edition-info.js",
"text": "/*\\\ntitle: $:/core/modules/utils/edition-info.js\ntype: application/javascript\nmodule-type: utils-node\n\nInformation about the available editions\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar fs = require(\"fs\"),\n\tpath = require(\"path\");\n\nvar editionInfo;\n\nexports.getEditionInfo = function() {\n\tif(!editionInfo) {\n\t\t// Enumerate the edition paths\n\t\tvar editionPaths = $tw.getLibraryItemSearchPaths($tw.config.editionsPath,$tw.config.editionsEnvVar);\n\t\teditionInfo = {};\n\t\tfor(var editionIndex=0; editionIndex<editionPaths.length; editionIndex++) {\n\t\t\tvar editionPath = editionPaths[editionIndex];\n\t\t\t// Enumerate the folders\n\t\t\tvar entries = fs.readdirSync(editionPath);\n\t\t\tfor(var entryIndex=0; entryIndex<entries.length; entryIndex++) {\n\t\t\t\tvar entry = entries[entryIndex];\n\t\t\t\t// Check if directories have a valid tiddlywiki.info\n\t\t\t\tif(!editionInfo[entry] && $tw.utils.isDirectory(path.resolve(editionPath,entry))) {\n\t\t\t\t\tvar info;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tinfo = JSON.parse(fs.readFileSync(path.resolve(editionPath,entry,\"tiddlywiki.info\"),\"utf8\"));\n\t\t\t\t\t} catch(ex) {\n\t\t\t\t\t}\n\t\t\t\t\tif(info) {\n\t\t\t\t\t\teditionInfo[entry] = info;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn editionInfo;\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "utils-node"
},
"$:/core/modules/utils/fakedom.js": {
"title": "$:/core/modules/utils/fakedom.js",
"text": "/*\\\ntitle: $:/core/modules/utils/fakedom.js\ntype: application/javascript\nmodule-type: global\n\nA barebones implementation of DOM interfaces needed by the rendering mechanism.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Sequence number used to enable us to track objects for testing\nvar sequenceNumber = null;\n\nvar bumpSequenceNumber = function(object) {\n\tif(sequenceNumber !== null) {\n\t\tobject.sequenceNumber = sequenceNumber++;\n\t}\n};\n\nvar TW_TextNode = function(text) {\n\tbumpSequenceNumber(this);\n\tthis.textContent = text + \"\";\n};\n\nObject.defineProperty(TW_TextNode.prototype, \"nodeType\", {\n\tget: function() {\n\t\treturn 3;\n\t}\n});\n\nObject.defineProperty(TW_TextNode.prototype, \"formattedTextContent\", {\n\tget: function() {\n\t\treturn this.textContent.replace(/(\\r?\\n)/g,\"\");\n\t}\n});\n\nvar TW_Element = function(tag,namespace) {\n\tbumpSequenceNumber(this);\n\tthis.isTiddlyWikiFakeDom = true;\n\tthis.tag = tag;\n\tthis.attributes = {};\n\tthis.isRaw = false;\n\tthis.children = [];\n\tthis.style = {};\n\tthis.namespaceURI = namespace || \"http://www.w3.org/1999/xhtml\";\n};\n\nObject.defineProperty(TW_Element.prototype, \"nodeType\", {\n\tget: function() {\n\t\treturn 1;\n\t}\n});\n\nTW_Element.prototype.getAttribute = function(name) {\n\tif(this.isRaw) {\n\t\tthrow \"Cannot getAttribute on a raw TW_Element\";\n\t}\n\treturn this.attributes[name];\n};\n\nTW_Element.prototype.setAttribute = function(name,value) {\n\tif(this.isRaw) {\n\t\tthrow \"Cannot setAttribute on a raw TW_Element\";\n\t}\n\tthis.attributes[name] = value + \"\";\n};\n\nTW_Element.prototype.setAttributeNS = function(namespace,name,value) {\n\tthis.setAttribute(name,value);\n};\n\nTW_Element.prototype.removeAttribute = function(name) {\n\tif(this.isRaw) {\n\t\tthrow \"Cannot removeAttribute on a raw TW_Element\";\n\t}\n\tif($tw.utils.hop(this.attributes,name)) {\n\t\tdelete this.attributes[name];\n\t}\n};\n\nTW_Element.prototype.appendChild = function(node) {\n\tthis.children.push(node);\n\tnode.parentNode = this;\n};\n\nTW_Element.prototype.insertBefore = function(node,nextSibling) {\n\tif(nextSibling) {\n\t\tvar p = this.children.indexOf(nextSibling);\n\t\tif(p !== -1) {\n\t\t\tthis.children.splice(p,0,node);\n\t\t\tnode.parentNode = this;\n\t\t} else {\n\t\t\tthis.appendChild(node);\n\t\t}\n\t} else {\n\t\tthis.appendChild(node);\n\t}\n};\n\nTW_Element.prototype.removeChild = function(node) {\n\tvar p = this.children.indexOf(node);\n\tif(p !== -1) {\n\t\tthis.children.splice(p,1);\n\t}\n};\n\nTW_Element.prototype.hasChildNodes = function() {\n\treturn !!this.children.length;\n};\n\nObject.defineProperty(TW_Element.prototype, \"childNodes\", {\n\tget: function() {\n\t\treturn this.children;\n\t}\n});\n\nObject.defineProperty(TW_Element.prototype, \"firstChild\", {\n\tget: function() {\n\t\treturn this.children[0];\n\t}\n});\n\nTW_Element.prototype.addEventListener = function(type,listener,useCapture) {\n\t// Do nothing\n};\n\nObject.defineProperty(TW_Element.prototype, \"tagName\", {\n\tget: function() {\n\t\treturn this.tag || \"\";\n\t}\n});\n\nObject.defineProperty(TW_Element.prototype, \"className\", {\n\tget: function() {\n\t\treturn this.attributes[\"class\"] || \"\";\n\t},\n\tset: function(value) {\n\t\tthis.attributes[\"class\"] = value + \"\";\n\t}\n});\n\nObject.defineProperty(TW_Element.prototype, \"value\", {\n\tget: function() {\n\t\treturn this.attributes.value || \"\";\n\t},\n\tset: function(value) {\n\t\tthis.attributes.value = value + \"\";\n\t}\n});\n\nObject.defineProperty(TW_Element.prototype, \"outerHTML\", {\n\tget: function() {\n\t\tvar output = [],attr,a,v;\n\t\toutput.push(\"<\",this.tag);\n\t\tif(this.attributes) {\n\t\t\tattr = [];\n\t\t\tfor(a in this.attributes) {\n\t\t\t\tattr.push(a);\n\t\t\t}\n\t\t\tattr.sort();\n\t\t\tfor(a=0; a<attr.length; a++) {\n\t\t\t\tv = this.attributes[attr[a]];\n\t\t\t\tif(v !== undefined) {\n\t\t\t\t\toutput.push(\" \",attr[a],\"=\\\"\",$tw.utils.htmlEncode(v),\"\\\"\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif(this.style) {\n\t\t\tvar style = [];\n\t\t\tfor(var s in this.style) {\n\t\t\t\tstyle.push(s + \":\" + this.style[s] + \";\");\n\t\t\t}\n\t\t\tif(style.length > 0) {\n\t\t\t\toutput.push(\" style=\\\"\",style.join(\"\"),\"\\\"\")\n\t\t\t}\n\t\t}\n\t\toutput.push(\">\");\n\t\tif($tw.config.htmlVoidElements.indexOf(this.tag) === -1) {\n\t\t\toutput.push(this.innerHTML);\n\t\t\toutput.push(\"</\",this.tag,\">\");\n\t\t}\n\t\treturn output.join(\"\");\n\t}\n});\n\nObject.defineProperty(TW_Element.prototype, \"innerHTML\", {\n\tget: function() {\n\t\tif(this.isRaw) {\n\t\t\treturn this.rawHTML;\n\t\t} else {\n\t\t\tvar b = [];\n\t\t\t$tw.utils.each(this.children,function(node) {\n\t\t\t\tif(node instanceof TW_Element) {\n\t\t\t\t\tb.push(node.outerHTML);\n\t\t\t\t} else if(node instanceof TW_TextNode) {\n\t\t\t\t\tb.push($tw.utils.htmlEncode(node.textContent));\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn b.join(\"\");\n\t\t}\n\t},\n\tset: function(value) {\n\t\tthis.isRaw = true;\n\t\tthis.rawHTML = value;\n\t\tthis.rawTextContent = null;\n\t}\n});\n\nObject.defineProperty(TW_Element.prototype, \"textInnerHTML\", {\n\tset: function(value) {\n\t\tif(this.isRaw) {\n\t\t\tthis.rawTextContent = value;\n\t\t} else {\n\t\t\tthrow \"Cannot set textInnerHTML of a non-raw TW_Element\";\n\t\t}\n\t}\n});\n\nObject.defineProperty(TW_Element.prototype, \"textContent\", {\n\tget: function() {\n\t\tif(this.isRaw) {\n\t\t\tif(this.rawTextContent === null) {\n\t\t\t\treturn \"\";\n\t\t\t} else {\n\t\t\t\treturn this.rawTextContent;\n\t\t\t}\n\t\t} else {\n\t\t\tvar b = [];\n\t\t\t$tw.utils.each(this.children,function(node) {\n\t\t\t\tb.push(node.textContent);\n\t\t\t});\n\t\t\treturn b.join(\"\");\n\t\t}\n\t},\n\tset: function(value) {\n\t\tthis.children = [new TW_TextNode(value)];\n\t}\n});\n\nObject.defineProperty(TW_Element.prototype, \"formattedTextContent\", {\n\tget: function() {\n\t\tif(this.isRaw) {\n\t\t\treturn \"\";\n\t\t} else {\n\t\t\tvar b = [],\n\t\t\t\tisBlock = $tw.config.htmlBlockElements.indexOf(this.tag) !== -1;\n\t\t\tif(isBlock) {\n\t\t\t\tb.push(\"\\n\");\n\t\t\t}\n\t\t\tif(this.tag === \"li\") {\n\t\t\t\tb.push(\"* \");\n\t\t\t}\n\t\t\t$tw.utils.each(this.children,function(node) {\n\t\t\t\tb.push(node.formattedTextContent);\n\t\t\t});\n\t\t\tif(isBlock) {\n\t\t\t\tb.push(\"\\n\");\n\t\t\t}\n\t\t\treturn b.join(\"\");\n\t\t}\n\t}\n});\n\nvar document = {\n\tsetSequenceNumber: function(value) {\n\t\tsequenceNumber = value;\n\t},\n\tcreateElementNS: function(namespace,tag) {\n\t\treturn new TW_Element(tag,namespace);\n\t},\n\tcreateElement: function(tag) {\n\t\treturn new TW_Element(tag);\n\t},\n\tcreateTextNode: function(text) {\n\t\treturn new TW_TextNode(text);\n\t},\n\tcompatMode: \"CSS1Compat\", // For KaTeX to know that we're not a browser in quirks mode\n\tisTiddlyWikiFakeDom: true\n};\n\nexports.fakeDocument = document;\n\n})();\n",
"type": "application/javascript",
"module-type": "global"
},
"$:/core/modules/utils/filesystem.js": {
"title": "$:/core/modules/utils/filesystem.js",
"text": "/*\\\ntitle: $:/core/modules/utils/filesystem.js\ntype: application/javascript\nmodule-type: utils-node\n\nFile system utilities\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar fs = require(\"fs\"),\n\tpath = require(\"path\");\n\n/*\nRecursively (and synchronously) copy a directory and all its content\n*/\nexports.copyDirectory = function(srcPath,dstPath) {\n\t// Remove any trailing path separators\n\tsrcPath = $tw.utils.removeTrailingSeparator(srcPath);\n\tdstPath = $tw.utils.removeTrailingSeparator(dstPath);\n\t// Create the destination directory\n\tvar err = $tw.utils.createDirectory(dstPath);\n\tif(err) {\n\t\treturn err;\n\t}\n\t// Function to copy a folder full of files\n\tvar copy = function(srcPath,dstPath) {\n\t\tvar srcStats = fs.lstatSync(srcPath),\n\t\t\tdstExists = fs.existsSync(dstPath);\n\t\tif(srcStats.isFile()) {\n\t\t\t$tw.utils.copyFile(srcPath,dstPath);\n\t\t} else if(srcStats.isDirectory()) {\n\t\t\tvar items = fs.readdirSync(srcPath);\n\t\t\tfor(var t=0; t<items.length; t++) {\n\t\t\t\tvar item = items[t],\n\t\t\t\t\terr = copy(srcPath + path.sep + item,dstPath + path.sep + item);\n\t\t\t\tif(err) {\n\t\t\t\t\treturn err;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\tcopy(srcPath,dstPath);\n\treturn null;\n};\n\n/*\nCopy a file\n*/\nvar FILE_BUFFER_LENGTH = 64 * 1024,\n\tfileBuffer;\n\nexports.copyFile = function(srcPath,dstPath) {\n\t// Create buffer if required\n\tif(!fileBuffer) {\n\t\tfileBuffer = Buffer.alloc(FILE_BUFFER_LENGTH);\n\t}\n\t// Create any directories in the destination\n\t$tw.utils.createDirectory(path.dirname(dstPath));\n\t// Copy the file\n\tvar srcFile = fs.openSync(srcPath,\"r\"),\n\t\tdstFile = fs.openSync(dstPath,\"w\"),\n\t\tbytesRead = 1,\n\t\tpos = 0;\n\twhile (bytesRead > 0) {\n\t\tbytesRead = fs.readSync(srcFile,fileBuffer,0,FILE_BUFFER_LENGTH,pos);\n\t\tfs.writeSync(dstFile,fileBuffer,0,bytesRead);\n\t\tpos += bytesRead;\n\t}\n\tfs.closeSync(srcFile);\n\tfs.closeSync(dstFile);\n\treturn null;\n};\n\n/*\nRemove trailing path separator\n*/\nexports.removeTrailingSeparator = function(dirPath) {\n\tvar len = dirPath.length;\n\tif(dirPath.charAt(len-1) === path.sep) {\n\t\tdirPath = dirPath.substr(0,len-1);\n\t}\n\treturn dirPath;\n};\n\n/*\nRecursively create a directory\n*/\nexports.createDirectory = function(dirPath) {\n\tif(dirPath.substr(dirPath.length-1,1) !== path.sep) {\n\t\tdirPath = dirPath + path.sep;\n\t}\n\tvar pos = 1;\n\tpos = dirPath.indexOf(path.sep,pos);\n\twhile(pos !== -1) {\n\t\tvar subDirPath = dirPath.substr(0,pos);\n\t\tif(!$tw.utils.isDirectory(subDirPath)) {\n\t\t\ttry {\n\t\t\t\tfs.mkdirSync(subDirPath);\n\t\t\t} catch(e) {\n\t\t\t\treturn \"Error creating directory '\" + subDirPath + \"'\";\n\t\t\t}\n\t\t}\n\t\tpos = dirPath.indexOf(path.sep,pos + 1);\n\t}\n\treturn null;\n};\n\n/*\nRecursively create directories needed to contain a specified file\n*/\nexports.createFileDirectories = function(filePath) {\n\treturn $tw.utils.createDirectory(path.dirname(filePath));\n};\n\n/*\nRecursively delete a directory\n*/\nexports.deleteDirectory = function(dirPath) {\n\tif(fs.existsSync(dirPath)) {\n\t\tvar entries = fs.readdirSync(dirPath);\n\t\tfor(var entryIndex=0; entryIndex<entries.length; entryIndex++) {\n\t\t\tvar currPath = dirPath + path.sep + entries[entryIndex];\n\t\t\tif(fs.lstatSync(currPath).isDirectory()) {\n\t\t\t\t$tw.utils.deleteDirectory(currPath);\n\t\t\t} else {\n\t\t\t\tfs.unlinkSync(currPath);\n\t\t\t}\n\t\t}\n\tfs.rmdirSync(dirPath);\n\t}\n\treturn null;\n};\n\n/*\nCheck if a path identifies a directory\n*/\nexports.isDirectory = function(dirPath) {\n\treturn fs.existsSync(dirPath) && fs.statSync(dirPath).isDirectory();\n};\n\n/*\nCheck if a path identifies a directory that is empty\n*/\nexports.isDirectoryEmpty = function(dirPath) {\n\tif(!$tw.utils.isDirectory(dirPath)) {\n\t\treturn false;\n\t}\n\tvar files = fs.readdirSync(dirPath),\n\t\tempty = true;\n\t$tw.utils.each(files,function(file,index) {\n\t\tif(file.charAt(0) !== \".\") {\n\t\t\tempty = false;\n\t\t}\n\t});\n\treturn empty;\n};\n\n/*\nRecursively delete a tree of empty directories\n*/\nexports.deleteEmptyDirs = function(dirpath,callback) {\n\tvar self = this;\n\tfs.readdir(dirpath,function(err,files) {\n\t\tif(err) {\n\t\t\treturn callback(err);\n\t\t}\n\t\tif(files.length > 0) {\n\t\t\treturn callback(null);\n\t\t}\n\t\tfs.rmdir(dirpath,function(err) {\n\t\t\tif(err) {\n\t\t\t\treturn callback(err);\n\t\t\t}\n\t\t\tself.deleteEmptyDirs(path.dirname(dirpath),callback);\n\t\t});\n\t});\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "utils-node"
},
"$:/core/modules/utils/logger.js": {
"title": "$:/core/modules/utils/logger.js",
"text": "/*\\\ntitle: $:/core/modules/utils/logger.js\ntype: application/javascript\nmodule-type: utils\n\nA basic logging implementation\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar ALERT_TAG = \"$:/tags/Alert\";\n\n/*\nMake a new logger\n*/\nfunction Logger(componentName,options) {\n\toptions = options || {};\n\tthis.componentName = componentName || \"\";\n\tthis.colour = options.colour || \"white\";\n\tthis.enable = \"enable\" in options ? options.enable : true;\n}\n\n/*\nLog a message\n*/\nLogger.prototype.log = function(/* args */) {\n\tif(this.enable && console !== undefined && console.log !== undefined) {\n\t\treturn Function.apply.call(console.log, console, [$tw.utils.terminalColour(this.colour),this.componentName + \":\"].concat(Array.prototype.slice.call(arguments,0)).concat($tw.utils.terminalColour()));\n\t}\n};\n\n/*\nAlert a message\n*/\nLogger.prototype.alert = function(/* args */) {\n\tif(this.enable) {\n\t\t// Prepare the text of the alert\n\t\tvar text = Array.prototype.join.call(arguments,\" \");\n\t\t// Create alert tiddlers in the browser\n\t\tif($tw.browser) {\n\t\t\t// Check if there is an existing alert with the same text and the same component\n\t\t\tvar existingAlerts = $tw.wiki.getTiddlersWithTag(ALERT_TAG),\n\t\t\t\talertFields,\n\t\t\t\texistingCount,\n\t\t\t\tself = this;\n\t\t\t$tw.utils.each(existingAlerts,function(title) {\n\t\t\t\tvar tiddler = $tw.wiki.getTiddler(title);\n\t\t\t\tif(tiddler.fields.text === text && tiddler.fields.component === self.componentName && tiddler.fields.modified && (!alertFields || tiddler.fields.modified < alertFields.modified)) {\n\t\t\t\t\t\talertFields = $tw.utils.extend({},tiddler.fields);\n\t\t\t\t}\n\t\t\t});\n\t\t\tif(alertFields) {\n\t\t\t\texistingCount = alertFields.count || 1;\n\t\t\t} else {\n\t\t\t\talertFields = {\n\t\t\t\t\ttitle: $tw.wiki.generateNewTitle(\"$:/temp/alerts/alert\",{prefix: \"\"}),\n\t\t\t\t\ttext: text,\n\t\t\t\t\ttags: [ALERT_TAG],\n\t\t\t\t\tcomponent: this.componentName\n\t\t\t\t};\n\t\t\t\texistingCount = 0;\n\t\t\t}\n\t\t\talertFields.modified = new Date();\n\t\t\tif(++existingCount > 1) {\n\t\t\t\talertFields.count = existingCount;\n\t\t\t} else {\n\t\t\t\talertFields.count = undefined;\n\t\t\t}\n\t\t\t$tw.wiki.addTiddler(new $tw.Tiddler(alertFields));\n\t\t\t// Log the alert as well\n\t\t\tthis.log.apply(this,Array.prototype.slice.call(arguments,0));\n\t\t} else {\n\t\t\t// Print an orange message to the console if not in the browser\n\t\t\tconsole.error(\"\\x1b[1;33m\" + text + \"\\x1b[0m\");\n\t\t}\t\t\n\t}\n};\n\nexports.Logger = Logger;\n\n})();\n",
"type": "application/javascript",
"module-type": "utils"
},
"$:/core/modules/utils/parsetree.js": {
"title": "$:/core/modules/utils/parsetree.js",
"text": "/*\\\ntitle: $:/core/modules/utils/parsetree.js\ntype: application/javascript\nmodule-type: utils\n\nParse tree utility functions.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.addAttributeToParseTreeNode = function(node,name,value) {\n\tnode.attributes = node.attributes || {};\n\tnode.attributes[name] = {type: \"string\", value: value};\n};\n\nexports.getAttributeValueFromParseTreeNode = function(node,name,defaultValue) {\n\tif(node.attributes && node.attributes[name] && node.attributes[name].value !== undefined) {\n\t\treturn node.attributes[name].value;\n\t}\n\treturn defaultValue;\n};\n\nexports.addClassToParseTreeNode = function(node,classString) {\n\tvar classes = [];\n\tnode.attributes = node.attributes || {};\n\tnode.attributes[\"class\"] = node.attributes[\"class\"] || {type: \"string\", value: \"\"};\n\tif(node.attributes[\"class\"].type === \"string\") {\n\t\tif(node.attributes[\"class\"].value !== \"\") {\n\t\t\tclasses = node.attributes[\"class\"].value.split(\" \");\n\t\t}\n\t\tif(classString !== \"\") {\n\t\t\t$tw.utils.pushTop(classes,classString.split(\" \"));\n\t\t}\n\t\tnode.attributes[\"class\"].value = classes.join(\" \");\n\t}\n};\n\nexports.addStyleToParseTreeNode = function(node,name,value) {\n\t\tnode.attributes = node.attributes || {};\n\t\tnode.attributes.style = node.attributes.style || {type: \"string\", value: \"\"};\n\t\tif(node.attributes.style.type === \"string\") {\n\t\t\tnode.attributes.style.value += name + \":\" + value + \";\";\n\t\t}\n};\n\nexports.findParseTreeNode = function(nodeArray,search) {\n\tfor(var t=0; t<nodeArray.length; t++) {\n\t\tif(nodeArray[t].type === search.type && nodeArray[t].tag === search.tag) {\n\t\t\treturn nodeArray[t];\n\t\t}\n\t}\n\treturn undefined;\n};\n\n/*\nHelper to get the text of a parse tree node or array of nodes\n*/\nexports.getParseTreeText = function getParseTreeText(tree) {\n\tvar output = [];\n\tif($tw.utils.isArray(tree)) {\n\t\t$tw.utils.each(tree,function(node) {\n\t\t\toutput.push(getParseTreeText(node));\n\t\t});\n\t} else {\n\t\tif(tree.type === \"text\") {\n\t\t\toutput.push(tree.text);\n\t\t}\n\t\tif(tree.children) {\n\t\t\treturn getParseTreeText(tree.children);\n\t\t}\n\t}\n\treturn output.join(\"\");\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "utils"
},
"$:/core/modules/utils/performance.js": {
"title": "$:/core/modules/utils/performance.js",
"text": "/*\\\ntitle: $:/core/modules/utils/performance.js\ntype: application/javascript\nmodule-type: global\n\nPerformance measurement.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nfunction Performance(enabled) {\n\tthis.enabled = !!enabled;\n\tthis.measures = {}; // Hashmap of current values of measurements\n\tthis.logger = new $tw.utils.Logger(\"performance\");\n}\n\n/*\nWrap performance reporting around a top level function\n*/\nPerformance.prototype.report = function(name,fn) {\n\tvar self = this;\n\tif(this.enabled) {\n\t\treturn function() {\n\t\t\tself.measures = {};\n\t\t\tvar startTime = $tw.utils.timer(),\n\t\t\t\tresult = fn.apply(this,arguments);\n\t\t\tself.logger.log(name + \": \" + $tw.utils.timer(startTime).toFixed(2) + \"ms\");\n\t\t\tfor(var m in self.measures) {\n\t\t\t\tself.logger.log(\"+\" + m + \": \" + self.measures[m].toFixed(2) + \"ms\");\n\t\t\t}\n\t\t\treturn result;\n\t\t};\n\t} else {\n\t\treturn fn;\n\t}\n};\n\n/*\nWrap performance measurements around a subfunction\n*/\nPerformance.prototype.measure = function(name,fn) {\n\tvar self = this;\n\tif(this.enabled) {\n\t\treturn function() {\n\t\t\tvar startTime = $tw.utils.timer(),\n\t\t\t\tresult = fn.apply(this,arguments),\n\t\t\t\tvalue = self.measures[name] || 0;\n\t\t\tself.measures[name] = value + $tw.utils.timer(startTime);\n\t\t\treturn result;\n\t\t};\n\t} else {\n\t\treturn fn;\n\t}\n};\n\nexports.Performance = Performance;\n\n})();\n",
"type": "application/javascript",
"module-type": "global"
},
"$:/core/modules/utils/pluginmaker.js": {
"title": "$:/core/modules/utils/pluginmaker.js",
"text": "/*\\\ntitle: $:/core/modules/utils/pluginmaker.js\ntype: application/javascript\nmodule-type: utils\n\nA quick and dirty way to pack up plugins within the browser.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nRepack a plugin, and then delete any non-shadow payload tiddlers\n*/\nexports.repackPlugin = function(title,additionalTiddlers,excludeTiddlers) {\n\tadditionalTiddlers = additionalTiddlers || [];\n\texcludeTiddlers = excludeTiddlers || [];\n\t// Get the plugin tiddler\n\tvar pluginTiddler = $tw.wiki.getTiddler(title);\n\tif(!pluginTiddler) {\n\t\tthrow \"No such tiddler as \" + title;\n\t}\n\t// Extract the JSON\n\tvar jsonPluginTiddler;\n\ttry {\n\t\tjsonPluginTiddler = JSON.parse(pluginTiddler.fields.text);\n\t} catch(e) {\n\t\tthrow \"Cannot parse plugin tiddler \" + title + \"\\n\" + $tw.language.getString(\"Error/Caption\") + \": \" + e;\n\t}\n\t// Get the list of tiddlers\n\tvar tiddlers = Object.keys(jsonPluginTiddler.tiddlers);\n\t// Add the additional tiddlers\n\t$tw.utils.pushTop(tiddlers,additionalTiddlers);\n\t// Remove any excluded tiddlers\n\tfor(var t=tiddlers.length-1; t>=0; t--) {\n\t\tif(excludeTiddlers.indexOf(tiddlers[t]) !== -1) {\n\t\t\ttiddlers.splice(t,1);\n\t\t}\n\t}\n\t// Pack up the tiddlers into a block of JSON\n\tvar plugins = {};\n\t$tw.utils.each(tiddlers,function(title) {\n\t\tvar tiddler = $tw.wiki.getTiddler(title),\n\t\t\tfields = {};\n\t\t$tw.utils.each(tiddler.fields,function (value,name) {\n\t\t\tfields[name] = tiddler.getFieldString(name);\n\t\t});\n\t\tplugins[title] = fields;\n\t});\n\t// Retrieve and bump the version number\n\tvar pluginVersion = $tw.utils.parseVersion(pluginTiddler.getFieldString(\"version\") || \"0.0.0\") || {\n\t\t\tmajor: \"0\",\n\t\t\tminor: \"0\",\n\t\t\tpatch: \"0\"\n\t\t};\n\tpluginVersion.patch++;\n\tvar version = pluginVersion.major + \".\" + pluginVersion.minor + \".\" + pluginVersion.patch;\n\tif(pluginVersion.prerelease) {\n\t\tversion += \"-\" + pluginVersion.prerelease;\n\t}\n\tif(pluginVersion.build) {\n\t\tversion += \"+\" + pluginVersion.build;\n\t}\n\t// Save the tiddler\n\t$tw.wiki.addTiddler(new $tw.Tiddler(pluginTiddler,{text: JSON.stringify({tiddlers: plugins},null,4), version: version}));\n\t// Delete any non-shadow constituent tiddlers\n\t$tw.utils.each(tiddlers,function(title) {\n\t\tif($tw.wiki.tiddlerExists(title)) {\n\t\t\t$tw.wiki.deleteTiddler(title);\n\t\t}\n\t});\n\t// Trigger an autosave\n\t$tw.rootWidget.dispatchEvent({type: \"tm-auto-save-wiki\"});\n\t// Return a heartwarming confirmation\n\treturn \"Plugin \" + title + \" successfully saved\";\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "utils"
},
"$:/core/modules/utils/transliterate.js": {
"title": "$:/core/modules/utils/transliterate.js",
"text": "/*\\\ntitle: $:/core/modules/utils/transliterate.js\ntype: application/javascript\nmodule-type: utils\n\nTransliteration static utility functions.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nTransliterate string to ASCII\n\n(Some pairs taken from http://semplicewebsites.com/removing-accents-javascript)\n*/\nexports.transliterationPairs = {\n\t\"Á\":\"A\",\n\t\"Ă\":\"A\",\n\t\"Ắ\":\"A\",\n\t\"Ặ\":\"A\",\n\t\"Ằ\":\"A\",\n\t\"Ẳ\":\"A\",\n\t\"Ẵ\":\"A\",\n\t\"Ǎ\":\"A\",\n\t\"Â\":\"A\",\n\t\"Ấ\":\"A\",\n\t\"Ậ\":\"A\",\n\t\"Ầ\":\"A\",\n\t\"Ẩ\":\"A\",\n\t\"Ẫ\":\"A\",\n\t\"Ä\":\"A\",\n\t\"Ǟ\":\"A\",\n\t\"Ȧ\":\"A\",\n\t\"Ǡ\":\"A\",\n\t\"Ạ\":\"A\",\n\t\"Ȁ\":\"A\",\n\t\"À\":\"A\",\n\t\"Ả\":\"A\",\n\t\"Ȃ\":\"A\",\n\t\"Ā\":\"A\",\n\t\"Ą\":\"A\",\n\t\"Å\":\"A\",\n\t\"Ǻ\":\"A\",\n\t\"Ḁ\":\"A\",\n\t\"Ⱥ\":\"A\",\n\t\"Ã\":\"A\",\n\t\"Ꜳ\":\"AA\",\n\t\"Æ\":\"AE\",\n\t\"Ǽ\":\"AE\",\n\t\"Ǣ\":\"AE\",\n\t\"Ꜵ\":\"AO\",\n\t\"Ꜷ\":\"AU\",\n\t\"Ꜹ\":\"AV\",\n\t\"Ꜻ\":\"AV\",\n\t\"Ꜽ\":\"AY\",\n\t\"Ḃ\":\"B\",\n\t\"Ḅ\":\"B\",\n\t\"Ɓ\":\"B\",\n\t\"Ḇ\":\"B\",\n\t\"Ƀ\":\"B\",\n\t\"Ƃ\":\"B\",\n\t\"Ć\":\"C\",\n\t\"Č\":\"C\",\n\t\"Ç\":\"C\",\n\t\"Ḉ\":\"C\",\n\t\"Ĉ\":\"C\",\n\t\"Ċ\":\"C\",\n\t\"Ƈ\":\"C\",\n\t\"Ȼ\":\"C\",\n\t\"Ď\":\"D\",\n\t\"Ḑ\":\"D\",\n\t\"Ḓ\":\"D\",\n\t\"Ḋ\":\"D\",\n\t\"Ḍ\":\"D\",\n\t\"Ɗ\":\"D\",\n\t\"Ḏ\":\"D\",\n\t\"Dz\":\"D\",\n\t\"Dž\":\"D\",\n\t\"Đ\":\"D\",\n\t\"Ƌ\":\"D\",\n\t\"DZ\":\"DZ\",\n\t\"DŽ\":\"DZ\",\n\t\"É\":\"E\",\n\t\"Ĕ\":\"E\",\n\t\"Ě\":\"E\",\n\t\"Ȩ\":\"E\",\n\t\"Ḝ\":\"E\",\n\t\"Ê\":\"E\",\n\t\"Ế\":\"E\",\n\t\"Ệ\":\"E\",\n\t\"Ề\":\"E\",\n\t\"Ể\":\"E\",\n\t\"Ễ\":\"E\",\n\t\"Ḙ\":\"E\",\n\t\"Ë\":\"E\",\n\t\"Ė\":\"E\",\n\t\"Ẹ\":\"E\",\n\t\"Ȅ\":\"E\",\n\t\"È\":\"E\",\n\t\"Ẻ\":\"E\",\n\t\"Ȇ\":\"E\",\n\t\"Ē\":\"E\",\n\t\"Ḗ\":\"E\",\n\t\"Ḕ\":\"E\",\n\t\"Ę\":\"E\",\n\t\"Ɇ\":\"E\",\n\t\"Ẽ\":\"E\",\n\t\"Ḛ\":\"E\",\n\t\"Ꝫ\":\"ET\",\n\t\"Ḟ\":\"F\",\n\t\"Ƒ\":\"F\",\n\t\"Ǵ\":\"G\",\n\t\"Ğ\":\"G\",\n\t\"Ǧ\":\"G\",\n\t\"Ģ\":\"G\",\n\t\"Ĝ\":\"G\",\n\t\"Ġ\":\"G\",\n\t\"Ɠ\":\"G\",\n\t\"Ḡ\":\"G\",\n\t\"Ǥ\":\"G\",\n\t\"Ḫ\":\"H\",\n\t\"Ȟ\":\"H\",\n\t\"Ḩ\":\"H\",\n\t\"Ĥ\":\"H\",\n\t\"Ⱨ\":\"H\",\n\t\"Ḧ\":\"H\",\n\t\"Ḣ\":\"H\",\n\t\"Ḥ\":\"H\",\n\t\"Ħ\":\"H\",\n\t\"Í\":\"I\",\n\t\"Ĭ\":\"I\",\n\t\"Ǐ\":\"I\",\n\t\"Î\":\"I\",\n\t\"Ï\":\"I\",\n\t\"Ḯ\":\"I\",\n\t\"İ\":\"I\",\n\t\"Ị\":\"I\",\n\t\"Ȉ\":\"I\",\n\t\"Ì\":\"I\",\n\t\"Ỉ\":\"I\",\n\t\"Ȋ\":\"I\",\n\t\"Ī\":\"I\",\n\t\"Į\":\"I\",\n\t\"Ɨ\":\"I\",\n\t\"Ĩ\":\"I\",\n\t\"Ḭ\":\"I\",\n\t\"Ꝺ\":\"D\",\n\t\"Ꝼ\":\"F\",\n\t\"Ᵹ\":\"G\",\n\t\"Ꞃ\":\"R\",\n\t\"Ꞅ\":\"S\",\n\t\"Ꞇ\":\"T\",\n\t\"Ꝭ\":\"IS\",\n\t\"Ĵ\":\"J\",\n\t\"Ɉ\":\"J\",\n\t\"Ḱ\":\"K\",\n\t\"Ǩ\":\"K\",\n\t\"Ķ\":\"K\",\n\t\"Ⱪ\":\"K\",\n\t\"Ꝃ\":\"K\",\n\t\"Ḳ\":\"K\",\n\t\"Ƙ\":\"K\",\n\t\"Ḵ\":\"K\",\n\t\"Ꝁ\":\"K\",\n\t\"Ꝅ\":\"K\",\n\t\"Ĺ\":\"L\",\n\t\"Ƚ\":\"L\",\n\t\"Ľ\":\"L\",\n\t\"Ļ\":\"L\",\n\t\"Ḽ\":\"L\",\n\t\"Ḷ\":\"L\",\n\t\"Ḹ\":\"L\",\n\t\"Ⱡ\":\"L\",\n\t\"Ꝉ\":\"L\",\n\t\"Ḻ\":\"L\",\n\t\"Ŀ\":\"L\",\n\t\"Ɫ\":\"L\",\n\t\"Lj\":\"L\",\n\t\"Ł\":\"L\",\n\t\"LJ\":\"LJ\",\n\t\"Ḿ\":\"M\",\n\t\"Ṁ\":\"M\",\n\t\"Ṃ\":\"M\",\n\t\"Ɱ\":\"M\",\n\t\"Ń\":\"N\",\n\t\"Ň\":\"N\",\n\t\"Ņ\":\"N\",\n\t\"Ṋ\":\"N\",\n\t\"Ṅ\":\"N\",\n\t\"Ṇ\":\"N\",\n\t\"Ǹ\":\"N\",\n\t\"Ɲ\":\"N\",\n\t\"Ṉ\":\"N\",\n\t\"Ƞ\":\"N\",\n\t\"Nj\":\"N\",\n\t\"Ñ\":\"N\",\n\t\"NJ\":\"NJ\",\n\t\"Ó\":\"O\",\n\t\"Ŏ\":\"O\",\n\t\"Ǒ\":\"O\",\n\t\"Ô\":\"O\",\n\t\"Ố\":\"O\",\n\t\"Ộ\":\"O\",\n\t\"Ồ\":\"O\",\n\t\"Ổ\":\"O\",\n\t\"Ỗ\":\"O\",\n\t\"Ö\":\"O\",\n\t\"Ȫ\":\"O\",\n\t\"Ȯ\":\"O\",\n\t\"Ȱ\":\"O\",\n\t\"Ọ\":\"O\",\n\t\"Ő\":\"O\",\n\t\"Ȍ\":\"O\",\n\t\"Ò\":\"O\",\n\t\"Ỏ\":\"O\",\n\t\"Ơ\":\"O\",\n\t\"Ớ\":\"O\",\n\t\"Ợ\":\"O\",\n\t\"Ờ\":\"O\",\n\t\"Ở\":\"O\",\n\t\"Ỡ\":\"O\",\n\t\"Ȏ\":\"O\",\n\t\"Ꝋ\":\"O\",\n\t\"Ꝍ\":\"O\",\n\t\"Ō\":\"O\",\n\t\"Ṓ\":\"O\",\n\t\"Ṑ\":\"O\",\n\t\"Ɵ\":\"O\",\n\t\"Ǫ\":\"O\",\n\t\"Ǭ\":\"O\",\n\t\"Ø\":\"O\",\n\t\"Ǿ\":\"O\",\n\t\"Õ\":\"O\",\n\t\"Ṍ\":\"O\",\n\t\"Ṏ\":\"O\",\n\t\"Ȭ\":\"O\",\n\t\"Ƣ\":\"OI\",\n\t\"Ꝏ\":\"OO\",\n\t\"Ɛ\":\"E\",\n\t\"Ɔ\":\"O\",\n\t\"Ȣ\":\"OU\",\n\t\"Ṕ\":\"P\",\n\t\"Ṗ\":\"P\",\n\t\"Ꝓ\":\"P\",\n\t\"Ƥ\":\"P\",\n\t\"Ꝕ\":\"P\",\n\t\"Ᵽ\":\"P\",\n\t\"Ꝑ\":\"P\",\n\t\"Ꝙ\":\"Q\",\n\t\"Ꝗ\":\"Q\",\n\t\"Ŕ\":\"R\",\n\t\"Ř\":\"R\",\n\t\"Ŗ\":\"R\",\n\t\"Ṙ\":\"R\",\n\t\"Ṛ\":\"R\",\n\t\"Ṝ\":\"R\",\n\t\"Ȑ\":\"R\",\n\t\"Ȓ\":\"R\",\n\t\"Ṟ\":\"R\",\n\t\"Ɍ\":\"R\",\n\t\"Ɽ\":\"R\",\n\t\"Ꜿ\":\"C\",\n\t\"Ǝ\":\"E\",\n\t\"Ś\":\"S\",\n\t\"Ṥ\":\"S\",\n\t\"Š\":\"S\",\n\t\"Ṧ\":\"S\",\n\t\"Ş\":\"S\",\n\t\"Ŝ\":\"S\",\n\t\"Ș\":\"S\",\n\t\"Ṡ\":\"S\",\n\t\"Ṣ\":\"S\",\n\t\"Ṩ\":\"S\",\n\t\"Ť\":\"T\",\n\t\"Ţ\":\"T\",\n\t\"Ṱ\":\"T\",\n\t\"Ț\":\"T\",\n\t\"Ⱦ\":\"T\",\n\t\"Ṫ\":\"T\",\n\t\"Ṭ\":\"T\",\n\t\"Ƭ\":\"T\",\n\t\"Ṯ\":\"T\",\n\t\"Ʈ\":\"T\",\n\t\"Ŧ\":\"T\",\n\t\"Ɐ\":\"A\",\n\t\"Ꞁ\":\"L\",\n\t\"Ɯ\":\"M\",\n\t\"Ʌ\":\"V\",\n\t\"Ꜩ\":\"TZ\",\n\t\"Ú\":\"U\",\n\t\"Ŭ\":\"U\",\n\t\"Ǔ\":\"U\",\n\t\"Û\":\"U\",\n\t\"Ṷ\":\"U\",\n\t\"Ü\":\"U\",\n\t\"Ǘ\":\"U\",\n\t\"Ǚ\":\"U\",\n\t\"Ǜ\":\"U\",\n\t\"Ǖ\":\"U\",\n\t\"Ṳ\":\"U\",\n\t\"Ụ\":\"U\",\n\t\"Ű\":\"U\",\n\t\"Ȕ\":\"U\",\n\t\"Ù\":\"U\",\n\t\"Ủ\":\"U\",\n\t\"Ư\":\"U\",\n\t\"Ứ\":\"U\",\n\t\"Ự\":\"U\",\n\t\"Ừ\":\"U\",\n\t\"Ử\":\"U\",\n\t\"Ữ\":\"U\",\n\t\"Ȗ\":\"U\",\n\t\"Ū\":\"U\",\n\t\"Ṻ\":\"U\",\n\t\"Ų\":\"U\",\n\t\"Ů\":\"U\",\n\t\"Ũ\":\"U\",\n\t\"Ṹ\":\"U\",\n\t\"Ṵ\":\"U\",\n\t\"Ꝟ\":\"V\",\n\t\"Ṿ\":\"V\",\n\t\"Ʋ\":\"V\",\n\t\"Ṽ\":\"V\",\n\t\"Ꝡ\":\"VY\",\n\t\"Ẃ\":\"W\",\n\t\"Ŵ\":\"W\",\n\t\"Ẅ\":\"W\",\n\t\"Ẇ\":\"W\",\n\t\"Ẉ\":\"W\",\n\t\"Ẁ\":\"W\",\n\t\"Ⱳ\":\"W\",\n\t\"Ẍ\":\"X\",\n\t\"Ẋ\":\"X\",\n\t\"Ý\":\"Y\",\n\t\"Ŷ\":\"Y\",\n\t\"Ÿ\":\"Y\",\n\t\"Ẏ\":\"Y\",\n\t\"Ỵ\":\"Y\",\n\t\"Ỳ\":\"Y\",\n\t\"Ƴ\":\"Y\",\n\t\"Ỷ\":\"Y\",\n\t\"Ỿ\":\"Y\",\n\t\"Ȳ\":\"Y\",\n\t\"Ɏ\":\"Y\",\n\t\"Ỹ\":\"Y\",\n\t\"Ź\":\"Z\",\n\t\"Ž\":\"Z\",\n\t\"Ẑ\":\"Z\",\n\t\"Ⱬ\":\"Z\",\n\t\"Ż\":\"Z\",\n\t\"Ẓ\":\"Z\",\n\t\"Ȥ\":\"Z\",\n\t\"Ẕ\":\"Z\",\n\t\"Ƶ\":\"Z\",\n\t\"IJ\":\"IJ\",\n\t\"Œ\":\"OE\",\n\t\"ᴀ\":\"A\",\n\t\"ᴁ\":\"AE\",\n\t\"ʙ\":\"B\",\n\t\"ᴃ\":\"B\",\n\t\"ᴄ\":\"C\",\n\t\"ᴅ\":\"D\",\n\t\"ᴇ\":\"E\",\n\t\"ꜰ\":\"F\",\n\t\"ɢ\":\"G\",\n\t\"ʛ\":\"G\",\n\t\"ʜ\":\"H\",\n\t\"ɪ\":\"I\",\n\t\"ʁ\":\"R\",\n\t\"ᴊ\":\"J\",\n\t\"ᴋ\":\"K\",\n\t\"ʟ\":\"L\",\n\t\"ᴌ\":\"L\",\n\t\"ᴍ\":\"M\",\n\t\"ɴ\":\"N\",\n\t\"ᴏ\":\"O\",\n\t\"ɶ\":\"OE\",\n\t\"ᴐ\":\"O\",\n\t\"ᴕ\":\"OU\",\n\t\"ᴘ\":\"P\",\n\t\"ʀ\":\"R\",\n\t\"ᴎ\":\"N\",\n\t\"ᴙ\":\"R\",\n\t\"ꜱ\":\"S\",\n\t\"ᴛ\":\"T\",\n\t\"ⱻ\":\"E\",\n\t\"ᴚ\":\"R\",\n\t\"ᴜ\":\"U\",\n\t\"ᴠ\":\"V\",\n\t\"ᴡ\":\"W\",\n\t\"ʏ\":\"Y\",\n\t\"ᴢ\":\"Z\",\n\t\"á\":\"a\",\n\t\"ă\":\"a\",\n\t\"ắ\":\"a\",\n\t\"ặ\":\"a\",\n\t\"ằ\":\"a\",\n\t\"ẳ\":\"a\",\n\t\"ẵ\":\"a\",\n\t\"ǎ\":\"a\",\n\t\"â\":\"a\",\n\t\"ấ\":\"a\",\n\t\"ậ\":\"a\",\n\t\"ầ\":\"a\",\n\t\"ẩ\":\"a\",\n\t\"ẫ\":\"a\",\n\t\"ä\":\"a\",\n\t\"ǟ\":\"a\",\n\t\"ȧ\":\"a\",\n\t\"ǡ\":\"a\",\n\t\"ạ\":\"a\",\n\t\"ȁ\":\"a\",\n\t\"à\":\"a\",\n\t\"ả\":\"a\",\n\t\"ȃ\":\"a\",\n\t\"ā\":\"a\",\n\t\"ą\":\"a\",\n\t\"ᶏ\":\"a\",\n\t\"ẚ\":\"a\",\n\t\"å\":\"a\",\n\t\"ǻ\":\"a\",\n\t\"ḁ\":\"a\",\n\t\"ⱥ\":\"a\",\n\t\"ã\":\"a\",\n\t\"ꜳ\":\"aa\",\n\t\"æ\":\"ae\",\n\t\"ǽ\":\"ae\",\n\t\"ǣ\":\"ae\",\n\t\"ꜵ\":\"ao\",\n\t\"ꜷ\":\"au\",\n\t\"ꜹ\":\"av\",\n\t\"ꜻ\":\"av\",\n\t\"ꜽ\":\"ay\",\n\t\"ḃ\":\"b\",\n\t\"ḅ\":\"b\",\n\t\"ɓ\":\"b\",\n\t\"ḇ\":\"b\",\n\t\"ᵬ\":\"b\",\n\t\"ᶀ\":\"b\",\n\t\"ƀ\":\"b\",\n\t\"ƃ\":\"b\",\n\t\"ɵ\":\"o\",\n\t\"ć\":\"c\",\n\t\"č\":\"c\",\n\t\"ç\":\"c\",\n\t\"ḉ\":\"c\",\n\t\"ĉ\":\"c\",\n\t\"ɕ\":\"c\",\n\t\"ċ\":\"c\",\n\t\"ƈ\":\"c\",\n\t\"ȼ\":\"c\",\n\t\"ď\":\"d\",\n\t\"ḑ\":\"d\",\n\t\"ḓ\":\"d\",\n\t\"ȡ\":\"d\",\n\t\"ḋ\":\"d\",\n\t\"ḍ\":\"d\",\n\t\"ɗ\":\"d\",\n\t\"ᶑ\":\"d\",\n\t\"ḏ\":\"d\",\n\t\"ᵭ\":\"d\",\n\t\"ᶁ\":\"d\",\n\t\"đ\":\"d\",\n\t\"ɖ\":\"d\",\n\t\"ƌ\":\"d\",\n\t\"ı\":\"i\",\n\t\"ȷ\":\"j\",\n\t\"ɟ\":\"j\",\n\t\"ʄ\":\"j\",\n\t\"dz\":\"dz\",\n\t\"dž\":\"dz\",\n\t\"é\":\"e\",\n\t\"ĕ\":\"e\",\n\t\"ě\":\"e\",\n\t\"ȩ\":\"e\",\n\t\"ḝ\":\"e\",\n\t\"ê\":\"e\",\n\t\"ế\":\"e\",\n\t\"ệ\":\"e\",\n\t\"ề\":\"e\",\n\t\"ể\":\"e\",\n\t\"ễ\":\"e\",\n\t\"ḙ\":\"e\",\n\t\"ë\":\"e\",\n\t\"ė\":\"e\",\n\t\"ẹ\":\"e\",\n\t\"ȅ\":\"e\",\n\t\"è\":\"e\",\n\t\"ẻ\":\"e\",\n\t\"ȇ\":\"e\",\n\t\"ē\":\"e\",\n\t\"ḗ\":\"e\",\n\t\"ḕ\":\"e\",\n\t\"ⱸ\":\"e\",\n\t\"ę\":\"e\",\n\t\"ᶒ\":\"e\",\n\t\"ɇ\":\"e\",\n\t\"ẽ\":\"e\",\n\t\"ḛ\":\"e\",\n\t\"ꝫ\":\"et\",\n\t\"ḟ\":\"f\",\n\t\"ƒ\":\"f\",\n\t\"ᵮ\":\"f\",\n\t\"ᶂ\":\"f\",\n\t\"ǵ\":\"g\",\n\t\"ğ\":\"g\",\n\t\"ǧ\":\"g\",\n\t\"ģ\":\"g\",\n\t\"ĝ\":\"g\",\n\t\"ġ\":\"g\",\n\t\"ɠ\":\"g\",\n\t\"ḡ\":\"g\",\n\t\"ᶃ\":\"g\",\n\t\"ǥ\":\"g\",\n\t\"ḫ\":\"h\",\n\t\"ȟ\":\"h\",\n\t\"ḩ\":\"h\",\n\t\"ĥ\":\"h\",\n\t\"ⱨ\":\"h\",\n\t\"ḧ\":\"h\",\n\t\"ḣ\":\"h\",\n\t\"ḥ\":\"h\",\n\t\"ɦ\":\"h\",\n\t\"ẖ\":\"h\",\n\t\"ħ\":\"h\",\n\t\"ƕ\":\"hv\",\n\t\"í\":\"i\",\n\t\"ĭ\":\"i\",\n\t\"ǐ\":\"i\",\n\t\"î\":\"i\",\n\t\"ï\":\"i\",\n\t\"ḯ\":\"i\",\n\t\"ị\":\"i\",\n\t\"ȉ\":\"i\",\n\t\"ì\":\"i\",\n\t\"ỉ\":\"i\",\n\t\"ȋ\":\"i\",\n\t\"ī\":\"i\",\n\t\"į\":\"i\",\n\t\"ᶖ\":\"i\",\n\t\"ɨ\":\"i\",\n\t\"ĩ\":\"i\",\n\t\"ḭ\":\"i\",\n\t\"ꝺ\":\"d\",\n\t\"ꝼ\":\"f\",\n\t\"ᵹ\":\"g\",\n\t\"ꞃ\":\"r\",\n\t\"ꞅ\":\"s\",\n\t\"ꞇ\":\"t\",\n\t\"ꝭ\":\"is\",\n\t\"ǰ\":\"j\",\n\t\"ĵ\":\"j\",\n\t\"ʝ\":\"j\",\n\t\"ɉ\":\"j\",\n\t\"ḱ\":\"k\",\n\t\"ǩ\":\"k\",\n\t\"ķ\":\"k\",\n\t\"ⱪ\":\"k\",\n\t\"ꝃ\":\"k\",\n\t\"ḳ\":\"k\",\n\t\"ƙ\":\"k\",\n\t\"ḵ\":\"k\",\n\t\"ᶄ\":\"k\",\n\t\"ꝁ\":\"k\",\n\t\"ꝅ\":\"k\",\n\t\"ĺ\":\"l\",\n\t\"ƚ\":\"l\",\n\t\"ɬ\":\"l\",\n\t\"ľ\":\"l\",\n\t\"ļ\":\"l\",\n\t\"ḽ\":\"l\",\n\t\"ȴ\":\"l\",\n\t\"ḷ\":\"l\",\n\t\"ḹ\":\"l\",\n\t\"ⱡ\":\"l\",\n\t\"ꝉ\":\"l\",\n\t\"ḻ\":\"l\",\n\t\"ŀ\":\"l\",\n\t\"ɫ\":\"l\",\n\t\"ᶅ\":\"l\",\n\t\"ɭ\":\"l\",\n\t\"ł\":\"l\",\n\t\"lj\":\"lj\",\n\t\"ſ\":\"s\",\n\t\"ẜ\":\"s\",\n\t\"ẛ\":\"s\",\n\t\"ẝ\":\"s\",\n\t\"ḿ\":\"m\",\n\t\"ṁ\":\"m\",\n\t\"ṃ\":\"m\",\n\t\"ɱ\":\"m\",\n\t\"ᵯ\":\"m\",\n\t\"ᶆ\":\"m\",\n\t\"ń\":\"n\",\n\t\"ň\":\"n\",\n\t\"ņ\":\"n\",\n\t\"ṋ\":\"n\",\n\t\"ȵ\":\"n\",\n\t\"ṅ\":\"n\",\n\t\"ṇ\":\"n\",\n\t\"ǹ\":\"n\",\n\t\"ɲ\":\"n\",\n\t\"ṉ\":\"n\",\n\t\"ƞ\":\"n\",\n\t\"ᵰ\":\"n\",\n\t\"ᶇ\":\"n\",\n\t\"ɳ\":\"n\",\n\t\"ñ\":\"n\",\n\t\"nj\":\"nj\",\n\t\"ó\":\"o\",\n\t\"ŏ\":\"o\",\n\t\"ǒ\":\"o\",\n\t\"ô\":\"o\",\n\t\"ố\":\"o\",\n\t\"ộ\":\"o\",\n\t\"ồ\":\"o\",\n\t\"ổ\":\"o\",\n\t\"ỗ\":\"o\",\n\t\"ö\":\"o\",\n\t\"ȫ\":\"o\",\n\t\"ȯ\":\"o\",\n\t\"ȱ\":\"o\",\n\t\"ọ\":\"o\",\n\t\"ő\":\"o\",\n\t\"ȍ\":\"o\",\n\t\"ò\":\"o\",\n\t\"ỏ\":\"o\",\n\t\"ơ\":\"o\",\n\t\"ớ\":\"o\",\n\t\"ợ\":\"o\",\n\t\"ờ\":\"o\",\n\t\"ở\":\"o\",\n\t\"ỡ\":\"o\",\n\t\"ȏ\":\"o\",\n\t\"ꝋ\":\"o\",\n\t\"ꝍ\":\"o\",\n\t\"ⱺ\":\"o\",\n\t\"ō\":\"o\",\n\t\"ṓ\":\"o\",\n\t\"ṑ\":\"o\",\n\t\"ǫ\":\"o\",\n\t\"ǭ\":\"o\",\n\t\"ø\":\"o\",\n\t\"ǿ\":\"o\",\n\t\"õ\":\"o\",\n\t\"ṍ\":\"o\",\n\t\"ṏ\":\"o\",\n\t\"ȭ\":\"o\",\n\t\"ƣ\":\"oi\",\n\t\"ꝏ\":\"oo\",\n\t\"ɛ\":\"e\",\n\t\"ᶓ\":\"e\",\n\t\"ɔ\":\"o\",\n\t\"ᶗ\":\"o\",\n\t\"ȣ\":\"ou\",\n\t\"ṕ\":\"p\",\n\t\"ṗ\":\"p\",\n\t\"ꝓ\":\"p\",\n\t\"ƥ\":\"p\",\n\t\"ᵱ\":\"p\",\n\t\"ᶈ\":\"p\",\n\t\"ꝕ\":\"p\",\n\t\"ᵽ\":\"p\",\n\t\"ꝑ\":\"p\",\n\t\"ꝙ\":\"q\",\n\t\"ʠ\":\"q\",\n\t\"ɋ\":\"q\",\n\t\"ꝗ\":\"q\",\n\t\"ŕ\":\"r\",\n\t\"ř\":\"r\",\n\t\"ŗ\":\"r\",\n\t\"ṙ\":\"r\",\n\t\"ṛ\":\"r\",\n\t\"ṝ\":\"r\",\n\t\"ȑ\":\"r\",\n\t\"ɾ\":\"r\",\n\t\"ᵳ\":\"r\",\n\t\"ȓ\":\"r\",\n\t\"ṟ\":\"r\",\n\t\"ɼ\":\"r\",\n\t\"ᵲ\":\"r\",\n\t\"ᶉ\":\"r\",\n\t\"ɍ\":\"r\",\n\t\"ɽ\":\"r\",\n\t\"ↄ\":\"c\",\n\t\"ꜿ\":\"c\",\n\t\"ɘ\":\"e\",\n\t\"ɿ\":\"r\",\n\t\"ś\":\"s\",\n\t\"ṥ\":\"s\",\n\t\"š\":\"s\",\n\t\"ṧ\":\"s\",\n\t\"ş\":\"s\",\n\t\"ŝ\":\"s\",\n\t\"ș\":\"s\",\n\t\"ṡ\":\"s\",\n\t\"ṣ\":\"s\",\n\t\"ṩ\":\"s\",\n\t\"ʂ\":\"s\",\n\t\"ᵴ\":\"s\",\n\t\"ᶊ\":\"s\",\n\t\"ȿ\":\"s\",\n\t\"ɡ\":\"g\",\n\t\"ᴑ\":\"o\",\n\t\"ᴓ\":\"o\",\n\t\"ᴝ\":\"u\",\n\t\"ť\":\"t\",\n\t\"ţ\":\"t\",\n\t\"ṱ\":\"t\",\n\t\"ț\":\"t\",\n\t\"ȶ\":\"t\",\n\t\"ẗ\":\"t\",\n\t\"ⱦ\":\"t\",\n\t\"ṫ\":\"t\",\n\t\"ṭ\":\"t\",\n\t\"ƭ\":\"t\",\n\t\"ṯ\":\"t\",\n\t\"ᵵ\":\"t\",\n\t\"ƫ\":\"t\",\n\t\"ʈ\":\"t\",\n\t\"ŧ\":\"t\",\n\t\"ᵺ\":\"th\",\n\t\"ɐ\":\"a\",\n\t\"ᴂ\":\"ae\",\n\t\"ǝ\":\"e\",\n\t\"ᵷ\":\"g\",\n\t\"ɥ\":\"h\",\n\t\"ʮ\":\"h\",\n\t\"ʯ\":\"h\",\n\t\"ᴉ\":\"i\",\n\t\"ʞ\":\"k\",\n\t\"ꞁ\":\"l\",\n\t\"ɯ\":\"m\",\n\t\"ɰ\":\"m\",\n\t\"ᴔ\":\"oe\",\n\t\"ɹ\":\"r\",\n\t\"ɻ\":\"r\",\n\t\"ɺ\":\"r\",\n\t\"ⱹ\":\"r\",\n\t\"ʇ\":\"t\",\n\t\"ʌ\":\"v\",\n\t\"ʍ\":\"w\",\n\t\"ʎ\":\"y\",\n\t\"ꜩ\":\"tz\",\n\t\"ú\":\"u\",\n\t\"ŭ\":\"u\",\n\t\"ǔ\":\"u\",\n\t\"û\":\"u\",\n\t\"ṷ\":\"u\",\n\t\"ü\":\"u\",\n\t\"ǘ\":\"u\",\n\t\"ǚ\":\"u\",\n\t\"ǜ\":\"u\",\n\t\"ǖ\":\"u\",\n\t\"ṳ\":\"u\",\n\t\"ụ\":\"u\",\n\t\"ű\":\"u\",\n\t\"ȕ\":\"u\",\n\t\"ù\":\"u\",\n\t\"ủ\":\"u\",\n\t\"ư\":\"u\",\n\t\"ứ\":\"u\",\n\t\"ự\":\"u\",\n\t\"ừ\":\"u\",\n\t\"ử\":\"u\",\n\t\"ữ\":\"u\",\n\t\"ȗ\":\"u\",\n\t\"ū\":\"u\",\n\t\"ṻ\":\"u\",\n\t\"ų\":\"u\",\n\t\"ᶙ\":\"u\",\n\t\"ů\":\"u\",\n\t\"ũ\":\"u\",\n\t\"ṹ\":\"u\",\n\t\"ṵ\":\"u\",\n\t\"ᵫ\":\"ue\",\n\t\"ꝸ\":\"um\",\n\t\"ⱴ\":\"v\",\n\t\"ꝟ\":\"v\",\n\t\"ṿ\":\"v\",\n\t\"ʋ\":\"v\",\n\t\"ᶌ\":\"v\",\n\t\"ⱱ\":\"v\",\n\t\"ṽ\":\"v\",\n\t\"ꝡ\":\"vy\",\n\t\"ẃ\":\"w\",\n\t\"ŵ\":\"w\",\n\t\"ẅ\":\"w\",\n\t\"ẇ\":\"w\",\n\t\"ẉ\":\"w\",\n\t\"ẁ\":\"w\",\n\t\"ⱳ\":\"w\",\n\t\"ẘ\":\"w\",\n\t\"ẍ\":\"x\",\n\t\"ẋ\":\"x\",\n\t\"ᶍ\":\"x\",\n\t\"ý\":\"y\",\n\t\"ŷ\":\"y\",\n\t\"ÿ\":\"y\",\n\t\"ẏ\":\"y\",\n\t\"ỵ\":\"y\",\n\t\"ỳ\":\"y\",\n\t\"ƴ\":\"y\",\n\t\"ỷ\":\"y\",\n\t\"ỿ\":\"y\",\n\t\"ȳ\":\"y\",\n\t\"ẙ\":\"y\",\n\t\"ɏ\":\"y\",\n\t\"ỹ\":\"y\",\n\t\"ź\":\"z\",\n\t\"ž\":\"z\",\n\t\"ẑ\":\"z\",\n\t\"ʑ\":\"z\",\n\t\"ⱬ\":\"z\",\n\t\"ż\":\"z\",\n\t\"ẓ\":\"z\",\n\t\"ȥ\":\"z\",\n\t\"ẕ\":\"z\",\n\t\"ᵶ\":\"z\",\n\t\"ᶎ\":\"z\",\n\t\"ʐ\":\"z\",\n\t\"ƶ\":\"z\",\n\t\"ɀ\":\"z\",\n\t\"ff\":\"ff\",\n\t\"ffi\":\"ffi\",\n\t\"ffl\":\"ffl\",\n\t\"fi\":\"fi\",\n\t\"fl\":\"fl\",\n\t\"ij\":\"ij\",\n\t\"œ\":\"oe\",\n\t\"st\":\"st\",\n\t\"ₐ\":\"a\",\n\t\"ₑ\":\"e\",\n\t\"ᵢ\":\"i\",\n\t\"ⱼ\":\"j\",\n\t\"ₒ\":\"o\",\n\t\"ᵣ\":\"r\",\n\t\"ᵤ\":\"u\",\n\t\"ᵥ\":\"v\",\n\t\"ₓ\":\"x\",\n\t\"Ё\":\"YO\",\n\t\"Й\":\"I\",\n\t\"Ц\":\"TS\",\n\t\"У\":\"U\",\n\t\"К\":\"K\",\n\t\"Е\":\"E\",\n\t\"Н\":\"N\",\n\t\"Г\":\"G\",\n\t\"Ш\":\"SH\",\n\t\"Щ\":\"SCH\",\n\t\"З\":\"Z\",\n\t\"Х\":\"H\",\n\t\"Ъ\":\"'\",\n\t\"ё\":\"yo\",\n\t\"й\":\"i\",\n\t\"ц\":\"ts\",\n\t\"у\":\"u\",\n\t\"к\":\"k\",\n\t\"е\":\"e\",\n\t\"н\":\"n\",\n\t\"г\":\"g\",\n\t\"ш\":\"sh\",\n\t\"щ\":\"sch\",\n\t\"з\":\"z\",\n\t\"х\":\"h\",\n\t\"ъ\":\"'\",\n\t\"Ф\":\"F\",\n\t\"Ы\":\"I\",\n\t\"В\":\"V\",\n\t\"А\":\"a\",\n\t\"П\":\"P\",\n\t\"Р\":\"R\",\n\t\"О\":\"O\",\n\t\"Л\":\"L\",\n\t\"Д\":\"D\",\n\t\"Ж\":\"ZH\",\n\t\"Э\":\"E\",\n\t\"ф\":\"f\",\n\t\"ы\":\"i\",\n\t\"в\":\"v\",\n\t\"а\":\"a\",\n\t\"п\":\"p\",\n\t\"р\":\"r\",\n\t\"о\":\"o\",\n\t\"л\":\"l\",\n\t\"д\":\"d\",\n\t\"ж\":\"zh\",\n\t\"э\":\"e\",\n\t\"Я\":\"Ya\",\n\t\"Ч\":\"CH\",\n\t\"С\":\"S\",\n\t\"М\":\"M\",\n\t\"И\":\"I\",\n\t\"Т\":\"T\",\n\t\"Ь\":\"'\",\n\t\"Б\":\"B\",\n\t\"Ю\":\"YU\",\n\t\"я\":\"ya\",\n\t\"ч\":\"ch\",\n\t\"с\":\"s\",\n\t\"м\":\"m\",\n\t\"и\":\"i\",\n\t\"т\":\"t\",\n\t\"ь\":\"'\",\n\t\"б\":\"b\",\n\t\"ю\":\"yu\"\n};\n\nexports.transliterate = function(str) {\n\treturn str.replace(/[^A-Za-z0-9\\[\\] ]/g,function(ch) {\n\t\treturn exports.transliterationPairs[ch] || ch\n\t});\n};\n\nexports.transliterateToSafeASCII = function(str) {\n\treturn str.replace(/[^\\x00-\\x7F]/g,function(ch) {\n\t\treturn exports.transliterationPairs[ch] || \"\"\n\t});\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "utils"
},
"$:/core/modules/utils/utils.js": {
"title": "$:/core/modules/utils/utils.js",
"text": "/*\\\ntitle: $:/core/modules/utils/utils.js\ntype: application/javascript\nmodule-type: utils\n\nVarious static utility functions.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nDisplay a message, in colour if we're on a terminal\n*/\nexports.log = function(text,colour) {\n\tconsole.log($tw.node ? exports.terminalColour(colour) + text + exports.terminalColour() : text);\n};\n\nexports.terminalColour = function(colour) {\n\tif(!$tw.browser && $tw.node && process.stdout.isTTY) {\n\t\tif(colour) {\n\t\t\tvar code = exports.terminalColourLookup[colour];\n\t\t\tif(code) {\n\t\t\t\treturn \"\\x1b[\" + code + \"m\";\n\t\t\t}\n\t\t} else {\n\t\t\treturn \"\\x1b[0m\"; // Cancel colour\n\t\t}\n\t}\n\treturn \"\";\n};\n\nexports.terminalColourLookup = {\n\t\"black\": \"0;30\",\n\t\"red\": \"0;31\",\n\t\"green\": \"0;32\",\n\t\"brown/orange\": \"0;33\",\n\t\"blue\": \"0;34\",\n\t\"purple\": \"0;35\",\n\t\"cyan\": \"0;36\",\n\t\"light gray\": \"0;37\"\n};\n\n/*\nDisplay a warning, in colour if we're on a terminal\n*/\nexports.warning = function(text) {\n\texports.log(text,\"brown/orange\");\n};\n\n/*\nReturn the integer represented by the str (string).\nReturn the dflt (default) parameter if str is not a base-10 number.\n*/\nexports.getInt = function(str,deflt) {\n\tvar i = parseInt(str,10);\n\treturn isNaN(i) ? deflt : i;\n}\n\n/*\nRepeatedly replaces a substring within a string. Like String.prototype.replace, but without any of the default special handling of $ sequences in the replace string\n*/\nexports.replaceString = function(text,search,replace) {\n\treturn text.replace(search,function() {\n\t\treturn replace;\n\t});\n};\n\n/*\nRepeats a string\n*/\nexports.repeat = function(str,count) {\n\tvar result = \"\";\n\tfor(var t=0;t<count;t++) {\n\t\tresult += str;\n\t}\n\treturn result;\n};\n\n/*\nTrim whitespace from the start and end of a string\nThanks to Steven Levithan, http://blog.stevenlevithan.com/archives/faster-trim-javascript\n*/\nexports.trim = function(str) {\n\tif(typeof str === \"string\") {\n\t\treturn str.replace(/^\\s\\s*/, '').replace(/\\s\\s*$/, '');\n\t} else {\n\t\treturn str;\n\t}\n};\n\n/*\nFind the line break preceding a given position in a string\nReturns position immediately after that line break, or the start of the string\n*/\nexports.findPrecedingLineBreak = function(text,pos) {\n\tvar result = text.lastIndexOf(\"\\n\",pos - 1);\n\tif(result === -1) {\n\t\tresult = 0;\n\t} else {\n\t\tresult++;\n\t\tif(text.charAt(result) === \"\\r\") {\n\t\t\tresult++;\n\t\t}\n\t}\n\treturn result;\n};\n\n/*\nFind the line break following a given position in a string\n*/\nexports.findFollowingLineBreak = function(text,pos) {\n\t// Cut to just past the following line break, or to the end of the text\n\tvar result = text.indexOf(\"\\n\",pos);\n\tif(result === -1) {\n\t\tresult = text.length;\n\t} else {\n\t\tif(text.charAt(result) === \"\\r\") {\n\t\t\tresult++;\n\t\t}\n\t}\n\treturn result;\n};\n\n/*\nReturn the number of keys in an object\n*/\nexports.count = function(object) {\n\treturn Object.keys(object || {}).length;\n};\n\n/*\nCheck if an array is equal by value and by reference.\n*/\nexports.isArrayEqual = function(array1,array2) {\n\tif(array1 === array2) {\n\t\treturn true;\n\t}\n\tarray1 = array1 || [];\n\tarray2 = array2 || [];\n\tif(array1.length !== array2.length) {\n\t\treturn false;\n\t}\n\treturn array1.every(function(value,index) {\n\t\treturn value === array2[index];\n\t});\n};\n\n/*\nDetermine whether an array-item is an object-property\n*/\nexports.hopArray = function(object,array) {\n\tfor(var i=0; i<array.length; i++) {\n\t\tif($tw.utils.hop(object,array[i])) {\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n};\n\n/*\nPush entries onto an array, removing them first if they already exist in the array\n\tarray: array to modify (assumed to be free of duplicates)\n\tvalue: a single value to push or an array of values to push\n*/\nexports.pushTop = function(array,value) {\n\tvar t,p;\n\tif($tw.utils.isArray(value)) {\n\t\t// Remove any array entries that are duplicated in the new values\n\t\tif(value.length !== 0) {\n\t\t\tif(array.length !== 0) {\n\t\t\t\tif(value.length < array.length) {\n\t\t\t\t\tfor(t=0; t<value.length; t++) {\n\t\t\t\t\t\tp = array.indexOf(value[t]);\n\t\t\t\t\t\tif(p !== -1) {\n\t\t\t\t\t\t\tarray.splice(p,1);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tfor(t=array.length-1; t>=0; t--) {\n\t\t\t\t\t\tp = value.indexOf(array[t]);\n\t\t\t\t\t\tif(p !== -1) {\n\t\t\t\t\t\t\tarray.splice(t,1);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Push the values on top of the main array\n\t\t\tarray.push.apply(array,value);\n\t\t}\n\t} else {\n\t\tp = array.indexOf(value);\n\t\tif(p !== -1) {\n\t\t\tarray.splice(p,1);\n\t\t}\n\t\tarray.push(value);\n\t}\n\treturn array;\n};\n\n/*\nRemove entries from an array\n\tarray: array to modify\n\tvalue: a single value to remove, or an array of values to remove\n*/\nexports.removeArrayEntries = function(array,value) {\n\tvar t,p;\n\tif($tw.utils.isArray(value)) {\n\t\tfor(t=0; t<value.length; t++) {\n\t\t\tp = array.indexOf(value[t]);\n\t\t\tif(p !== -1) {\n\t\t\t\tarray.splice(p,1);\n\t\t\t}\n\t\t}\n\t} else {\n\t\tp = array.indexOf(value);\n\t\tif(p !== -1) {\n\t\t\tarray.splice(p,1);\n\t\t}\n\t}\n};\n\n/*\nCheck whether any members of a hashmap are present in another hashmap\n*/\nexports.checkDependencies = function(dependencies,changes) {\n\tvar hit = false;\n\t$tw.utils.each(changes,function(change,title) {\n\t\tif($tw.utils.hop(dependencies,title)) {\n\t\t\thit = true;\n\t\t}\n\t});\n\treturn hit;\n};\n\nexports.extend = function(object /* [, src] */) {\n\t$tw.utils.each(Array.prototype.slice.call(arguments, 1), function(source) {\n\t\tif(source) {\n\t\t\tfor(var property in source) {\n\t\t\t\tobject[property] = source[property];\n\t\t\t}\n\t\t}\n\t});\n\treturn object;\n};\n\nexports.deepCopy = function(object) {\n\tvar result,t;\n\tif($tw.utils.isArray(object)) {\n\t\t// Copy arrays\n\t\tresult = object.slice(0);\n\t} else if(typeof object === \"object\") {\n\t\tresult = {};\n\t\tfor(t in object) {\n\t\t\tif(object[t] !== undefined) {\n\t\t\t\tresult[t] = $tw.utils.deepCopy(object[t]);\n\t\t\t}\n\t\t}\n\t} else {\n\t\tresult = object;\n\t}\n\treturn result;\n};\n\nexports.extendDeepCopy = function(object,extendedProperties) {\n\tvar result = $tw.utils.deepCopy(object),t;\n\tfor(t in extendedProperties) {\n\t\tif(extendedProperties[t] !== undefined) {\n\t\t\tresult[t] = $tw.utils.deepCopy(extendedProperties[t]);\n\t\t}\n\t}\n\treturn result;\n};\n\nexports.deepFreeze = function deepFreeze(object) {\n\tvar property, key;\n\tif(object) {\n\t\tObject.freeze(object);\n\t\tfor(key in object) {\n\t\t\tproperty = object[key];\n\t\t\tif($tw.utils.hop(object,key) && (typeof property === \"object\") && !Object.isFrozen(property)) {\n\t\t\t\tdeepFreeze(property);\n\t\t\t}\n\t\t}\n\t}\n};\n\nexports.slowInSlowOut = function(t) {\n\treturn (1 - ((Math.cos(t * Math.PI) + 1) / 2));\n};\n\nexports.formatDateString = function(date,template) {\n\tvar result = \"\",\n\t\tt = template,\n\t\tmatches = [\n\t\t\t[/^0hh12/, function() {\n\t\t\t\treturn $tw.utils.pad($tw.utils.getHours12(date));\n\t\t\t}],\n\t\t\t[/^wYYYY/, function() {\n\t\t\t\treturn $tw.utils.getYearForWeekNo(date);\n\t\t\t}],\n\t\t\t[/^hh12/, function() {\n\t\t\t\treturn $tw.utils.getHours12(date);\n\t\t\t}],\n\t\t\t[/^DDth/, function() {\n\t\t\t\treturn date.getDate() + $tw.utils.getDaySuffix(date);\n\t\t\t}],\n\t\t\t[/^YYYY/, function() {\n\t\t\t\treturn date.getFullYear();\n\t\t\t}],\n\t\t\t[/^0hh/, function() {\n\t\t\t\treturn $tw.utils.pad(date.getHours());\n\t\t\t}],\n\t\t\t[/^0mm/, function() {\n\t\t\t\treturn $tw.utils.pad(date.getMinutes());\n\t\t\t}],\n\t\t\t[/^0ss/, function() {\n\t\t\t\treturn $tw.utils.pad(date.getSeconds());\n\t\t\t}],\n\t\t\t[/^0XXX/, function() {\n\t\t\t\treturn $tw.utils.pad(date.getMilliseconds());\n\t\t\t}],\n\t\t\t[/^0DD/, function() {\n\t\t\t\treturn $tw.utils.pad(date.getDate());\n\t\t\t}],\n\t\t\t[/^0MM/, function() {\n\t\t\t\treturn $tw.utils.pad(date.getMonth()+1);\n\t\t\t}],\n\t\t\t[/^0WW/, function() {\n\t\t\t\treturn $tw.utils.pad($tw.utils.getWeek(date));\n\t\t\t}],\n\t\t\t[/^ddd/, function() {\n\t\t\t\treturn $tw.language.getString(\"Date/Short/Day/\" + date.getDay());\n\t\t\t}],\n\t\t\t[/^mmm/, function() {\n\t\t\t\treturn $tw.language.getString(\"Date/Short/Month/\" + (date.getMonth() + 1));\n\t\t\t}],\n\t\t\t[/^DDD/, function() {\n\t\t\t\treturn $tw.language.getString(\"Date/Long/Day/\" + date.getDay());\n\t\t\t}],\n\t\t\t[/^MMM/, function() {\n\t\t\t\treturn $tw.language.getString(\"Date/Long/Month/\" + (date.getMonth() + 1));\n\t\t\t}],\n\t\t\t[/^TZD/, function() {\n\t\t\t\tvar tz = date.getTimezoneOffset(),\n\t\t\t\tatz = Math.abs(tz);\n\t\t\t\treturn (tz < 0 ? '+' : '-') + $tw.utils.pad(Math.floor(atz / 60)) + ':' + $tw.utils.pad(atz % 60);\n\t\t\t}],\n\t\t\t[/^wYY/, function() {\n\t\t\t\treturn $tw.utils.pad($tw.utils.getYearForWeekNo(date) - 2000);\n\t\t\t}],\n\t\t\t[/^[ap]m/, function() {\n\t\t\t\treturn $tw.utils.getAmPm(date).toLowerCase();\n\t\t\t}],\n\t\t\t[/^hh/, function() {\n\t\t\t\treturn date.getHours();\n\t\t\t}],\n\t\t\t[/^mm/, function() {\n\t\t\t\treturn date.getMinutes();\n\t\t\t}],\n\t\t\t[/^ss/, function() {\n\t\t\t\treturn date.getSeconds();\n\t\t\t}],\n\t\t\t[/^XXX/, function() {\n\t\t\t\treturn date.getMilliseconds();\n\t\t\t}],\n\t\t\t[/^[AP]M/, function() {\n\t\t\t\treturn $tw.utils.getAmPm(date).toUpperCase();\n\t\t\t}],\n\t\t\t[/^DD/, function() {\n\t\t\t\treturn date.getDate();\n\t\t\t}],\n\t\t\t[/^MM/, function() {\n\t\t\t\treturn date.getMonth() + 1;\n\t\t\t}],\n\t\t\t[/^WW/, function() {\n\t\t\t\treturn $tw.utils.getWeek(date);\n\t\t\t}],\n\t\t\t[/^YY/, function() {\n\t\t\t\treturn $tw.utils.pad(date.getFullYear() - 2000);\n\t\t\t}]\n\t\t];\n\t// If the user wants everything in UTC, shift the datestamp\n\t// Optimize for format string that essentially means\n\t// 'return raw UTC (tiddlywiki style) date string.'\n\tif(t.indexOf(\"[UTC]\") == 0 ) {\n\t\tif(t == \"[UTC]YYYY0MM0DD0hh0mm0ssXXX\")\n\t\t\treturn $tw.utils.stringifyDate(new Date());\n\t\tvar offset = date.getTimezoneOffset() ; // in minutes\n\t\tdate = new Date(date.getTime()+offset*60*1000) ;\n\t\tt = t.substr(5) ;\n\t}\n\twhile(t.length){\n\t\tvar matchString = \"\";\n\t\t$tw.utils.each(matches, function(m) {\n\t\t\tvar match = m[0].exec(t);\n\t\t\tif(match) {\n\t\t\t\tmatchString = m[1].call();\n\t\t\t\tt = t.substr(match[0].length);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t});\n\t\tif(matchString) {\n\t\t\tresult += matchString;\n\t\t} else {\n\t\t\tresult += t.charAt(0);\n\t\t\tt = t.substr(1);\n\t\t}\n\t}\n\tresult = result.replace(/\\\\(.)/g,\"$1\");\n\treturn result;\n};\n\nexports.getAmPm = function(date) {\n\treturn $tw.language.getString(\"Date/Period/\" + (date.getHours() >= 12 ? \"pm\" : \"am\"));\n};\n\nexports.getDaySuffix = function(date) {\n\treturn $tw.language.getString(\"Date/DaySuffix/\" + date.getDate());\n};\n\nexports.getWeek = function(date) {\n\tvar dt = new Date(date.getTime());\n\tvar d = dt.getDay();\n\tif(d === 0) {\n\t\td = 7; // JavaScript Sun=0, ISO Sun=7\n\t}\n\tdt.setTime(dt.getTime() + (4 - d) * 86400000);// shift day to Thurs of same week to calculate weekNo\n\tvar x = new Date(dt.getFullYear(),0,1);\n\tvar n = Math.floor((dt.getTime() - x.getTime()) / 86400000);\n\treturn Math.floor(n / 7) + 1;\n};\n\nexports.getYearForWeekNo = function(date) {\n\tvar dt = new Date(date.getTime());\n\tvar d = dt.getDay();\n\tif(d === 0) {\n\t\td = 7; // JavaScript Sun=0, ISO Sun=7\n\t}\n\tdt.setTime(dt.getTime() + (4 - d) * 86400000);// shift day to Thurs of same week\n\treturn dt.getFullYear();\n};\n\nexports.getHours12 = function(date) {\n\tvar h = date.getHours();\n\treturn h > 12 ? h-12 : ( h > 0 ? h : 12 );\n};\n\n/*\nConvert a date delta in milliseconds into a string representation of \"23 seconds ago\", \"27 minutes ago\" etc.\n\tdelta: delta in milliseconds\nReturns an object with these members:\n\tdescription: string describing the delta period\n\tupdatePeriod: time in millisecond until the string will be inaccurate\n*/\nexports.getRelativeDate = function(delta) {\n\tvar futurep = false;\n\tif(delta < 0) {\n\t\tdelta = -1 * delta;\n\t\tfuturep = true;\n\t}\n\tvar units = [\n\t\t{name: \"Years\", duration: 365 * 24 * 60 * 60 * 1000},\n\t\t{name: \"Months\", duration: (365/12) * 24 * 60 * 60 * 1000},\n\t\t{name: \"Days\", duration: 24 * 60 * 60 * 1000},\n\t\t{name: \"Hours\", duration: 60 * 60 * 1000},\n\t\t{name: \"Minutes\", duration: 60 * 1000},\n\t\t{name: \"Seconds\", duration: 1000}\n\t];\n\tfor(var t=0; t<units.length; t++) {\n\t\tvar result = Math.floor(delta / units[t].duration);\n\t\tif(result >= 2) {\n\t\t\treturn {\n\t\t\t\tdelta: delta,\n\t\t\t\tdescription: $tw.language.getString(\n\t\t\t\t\t\"RelativeDate/\" + (futurep ? \"Future\" : \"Past\") + \"/\" + units[t].name,\n\t\t\t\t\t{variables:\n\t\t\t\t\t\t{period: result.toString()}\n\t\t\t\t\t}\n\t\t\t\t),\n\t\t\t\tupdatePeriod: units[t].duration\n\t\t\t};\n\t\t}\n\t}\n\treturn {\n\t\tdelta: delta,\n\t\tdescription: $tw.language.getString(\n\t\t\t\"RelativeDate/\" + (futurep ? \"Future\" : \"Past\") + \"/Second\",\n\t\t\t{variables:\n\t\t\t\t{period: \"1\"}\n\t\t\t}\n\t\t),\n\t\tupdatePeriod: 1000\n\t};\n};\n\n// Convert & to \"&\", < to \"<\", > to \">\", \" to \""\"\nexports.htmlEncode = function(s) {\n\tif(s) {\n\t\treturn s.toString().replace(/&/mg,\"&\").replace(/</mg,\"<\").replace(/>/mg,\">\").replace(/\\\"/mg,\""\");\n\t} else {\n\t\treturn \"\";\n\t}\n};\n\n// Converts all HTML entities to their character equivalents\nexports.entityDecode = function(s) {\n\tvar converter = String.fromCodePoint || String.fromCharCode,\n\t\te = s.substr(1,s.length-2), // Strip the & and the ;\n\t\tc;\n\tif(e.charAt(0) === \"#\") {\n\t\tif(e.charAt(1) === \"x\" || e.charAt(1) === \"X\") {\n\t\t\tc = parseInt(e.substr(2),16);\n\t\t} else {\n\t\t\tc = parseInt(e.substr(1),10);\n\t\t}\n\t\tif(isNaN(c)) {\n\t\t\treturn s;\n\t\t} else {\n\t\t\treturn converter(c);\n\t\t}\n\t} else {\n\t\tc = $tw.config.htmlEntities[e];\n\t\tif(c) {\n\t\t\treturn converter(c);\n\t\t} else {\n\t\t\treturn s; // Couldn't convert it as an entity, just return it raw\n\t\t}\n\t}\n};\n\nexports.unescapeLineBreaks = function(s) {\n\treturn s.replace(/\\\\n/mg,\"\\n\").replace(/\\\\b/mg,\" \").replace(/\\\\s/mg,\"\\\\\").replace(/\\r/mg,\"\");\n};\n\n/*\n * Returns an escape sequence for given character. Uses \\x for characters <=\n * 0xFF to save space, \\u for the rest.\n *\n * The code needs to be in sync with th code template in the compilation\n * function for \"action\" nodes.\n */\n// Copied from peg.js, thanks to David Majda\nexports.escape = function(ch) {\n\tvar charCode = ch.charCodeAt(0);\n\tif(charCode <= 0xFF) {\n\t\treturn '\\\\x' + $tw.utils.pad(charCode.toString(16).toUpperCase());\n\t} else {\n\t\treturn '\\\\u' + $tw.utils.pad(charCode.toString(16).toUpperCase(),4);\n\t}\n};\n\n// Turns a string into a legal JavaScript string\n// Copied from peg.js, thanks to David Majda\nexports.stringify = function(s) {\n\t/*\n\t* ECMA-262, 5th ed., 7.8.4: All characters may appear literally in a string\n\t* literal except for the closing quote character, backslash, carriage return,\n\t* line separator, paragraph separator, and line feed. Any character may\n\t* appear in the form of an escape sequence.\n\t*\n\t* For portability, we also escape all non-ASCII characters.\n\t*/\n\treturn (s || \"\")\n\t\t.replace(/\\\\/g, '\\\\\\\\') // backslash\n\t\t.replace(/\"/g, '\\\\\"') // double quote character\n\t\t.replace(/'/g, \"\\\\'\") // single quote character\n\t\t.replace(/\\r/g, '\\\\r') // carriage return\n\t\t.replace(/\\n/g, '\\\\n') // line feed\n\t\t.replace(/[\\x00-\\x1f\\x80-\\uFFFF]/g, exports.escape); // non-ASCII characters\n};\n\n// Turns a string into a legal JSON string\n// Derived from peg.js, thanks to David Majda\nexports.jsonStringify = function(s) {\n\t// See http://www.json.org/\n\treturn (s || \"\")\n\t\t.replace(/\\\\/g, '\\\\\\\\') // backslash\n\t\t.replace(/\"/g, '\\\\\"') // double quote character\n\t\t.replace(/\\r/g, '\\\\r') // carriage return\n\t\t.replace(/\\n/g, '\\\\n') // line feed\n\t\t.replace(/\\x08/g, '\\\\b') // backspace\n\t\t.replace(/\\x0c/g, '\\\\f') // formfeed\n\t\t.replace(/\\t/g, '\\\\t') // tab\n\t\t.replace(/[\\x00-\\x1f\\x80-\\uFFFF]/g,function(s) {\n\t\t\treturn '\\\\u' + $tw.utils.pad(s.charCodeAt(0).toString(16).toUpperCase(),4);\n\t\t}); // non-ASCII characters\n};\n\n/*\nEscape the RegExp special characters with a preceding backslash\n*/\nexports.escapeRegExp = function(s) {\n return s.replace(/[\\-\\/\\\\\\^\\$\\*\\+\\?\\.\\(\\)\\|\\[\\]\\{\\}]/g, '\\\\$&');\n};\n\n// Checks whether a link target is external, i.e. not a tiddler title\nexports.isLinkExternal = function(to) {\n\tvar externalRegExp = /^(?:file|http|https|mailto|ftp|irc|news|data|skype):[^\\s<>{}\\[\\]`|\"\\\\^]+(?:\\/|\\b)/i;\n\treturn externalRegExp.test(to);\n};\n\nexports.nextTick = function(fn) {\n/*global window: false */\n\tif(typeof process === \"undefined\") {\n\t\t// Apparently it would be faster to use postMessage - http://dbaron.org/log/20100309-faster-timeouts\n\t\twindow.setTimeout(fn,4);\n\t} else {\n\t\tprocess.nextTick(fn);\n\t}\n};\n\n/*\nConvert a hyphenated CSS property name into a camel case one\n*/\nexports.unHyphenateCss = function(propName) {\n\treturn propName.replace(/-([a-z])/gi, function(match0,match1) {\n\t\treturn match1.toUpperCase();\n\t});\n};\n\n/*\nConvert a camelcase CSS property name into a dashed one (\"backgroundColor\" --> \"background-color\")\n*/\nexports.hyphenateCss = function(propName) {\n\treturn propName.replace(/([A-Z])/g, function(match0,match1) {\n\t\treturn \"-\" + match1.toLowerCase();\n\t});\n};\n\n/*\nParse a text reference of one of these forms:\n* title\n* !!field\n* title!!field\n* title##index\n* etc\nReturns an object with the following fields, all optional:\n* title: tiddler title\n* field: tiddler field name\n* index: JSON property index\n*/\nexports.parseTextReference = function(textRef) {\n\t// Separate out the title, field name and/or JSON indices\n\tvar reTextRef = /(?:(.*?)!!(.+))|(?:(.*?)##(.+))|(.*)/mg,\n\t\tmatch = reTextRef.exec(textRef),\n\t\tresult = {};\n\tif(match && reTextRef.lastIndex === textRef.length) {\n\t\t// Return the parts\n\t\tif(match[1]) {\n\t\t\tresult.title = match[1];\n\t\t}\n\t\tif(match[2]) {\n\t\t\tresult.field = match[2];\n\t\t}\n\t\tif(match[3]) {\n\t\t\tresult.title = match[3];\n\t\t}\n\t\tif(match[4]) {\n\t\t\tresult.index = match[4];\n\t\t}\n\t\tif(match[5]) {\n\t\t\tresult.title = match[5];\n\t\t}\n\t} else {\n\t\t// If we couldn't parse it\n\t\tresult.title = textRef\n\t}\n\treturn result;\n};\n\n/*\nChecks whether a string is a valid fieldname\n*/\nexports.isValidFieldName = function(name) {\n\tif(!name || typeof name !== \"string\") {\n\t\treturn false;\n\t}\n\tname = name.toLowerCase().trim();\n\tvar fieldValidatorRegEx = /^[a-z0-9\\-\\._]+$/mg;\n\treturn fieldValidatorRegEx.test(name);\n};\n\n/*\nExtract the version number from the meta tag or from the boot file\n*/\n\n// Browser version\nexports.extractVersionInfo = function() {\n\tif($tw.packageInfo) {\n\t\treturn $tw.packageInfo.version;\n\t} else {\n\t\tvar metatags = document.getElementsByTagName(\"meta\");\n\t\tfor(var t=0; t<metatags.length; t++) {\n\t\t\tvar m = metatags[t];\n\t\t\tif(m.name === \"tiddlywiki-version\") {\n\t\t\t\treturn m.content;\n\t\t\t}\n\t\t}\n\t}\n\treturn null;\n};\n\n/*\nGet the animation duration in ms\n*/\nexports.getAnimationDuration = function() {\n\treturn parseInt($tw.wiki.getTiddlerText(\"$:/config/AnimationDuration\",\"400\"),10);\n};\n\n/*\nHash a string to a number\nDerived from http://stackoverflow.com/a/15710692\n*/\nexports.hashString = function(str) {\n\treturn str.split(\"\").reduce(function(a,b) {\n\t\ta = ((a << 5) - a) + b.charCodeAt(0);\n\t\treturn a & a;\n\t},0);\n};\n\n/*\nDecode a base64 string\n*/\nexports.base64Decode = function(string64) {\n\tif($tw.browser) {\n\t\t// TODO\n\t\tthrow \"$tw.utils.base64Decode() doesn't work in the browser\";\n\t} else {\n\t\treturn Buffer.from(string64,\"base64\").toString();\n\t}\n};\n\n/*\nConvert a hashmap into a tiddler dictionary format sequence of name:value pairs\n*/\nexports.makeTiddlerDictionary = function(data) {\n\tvar output = [];\n\tfor(var name in data) {\n\t\toutput.push(name + \": \" + data[name]);\n\t}\n\treturn output.join(\"\\n\");\n};\n\n/*\nHigh resolution microsecond timer for profiling\n*/\nexports.timer = function(base) {\n\tvar m;\n\tif($tw.node) {\n\t\tvar r = process.hrtime();\n\t\tm = r[0] * 1e3 + (r[1] / 1e6);\n\t} else if(window.performance) {\n\t\tm = performance.now();\n\t} else {\n\t\tm = Date.now();\n\t}\n\tif(typeof base !== \"undefined\") {\n\t\tm = m - base;\n\t}\n\treturn m;\n};\n\n/*\nConvert text and content type to a data URI\n*/\nexports.makeDataUri = function(text,type) {\n\ttype = type || \"text/vnd.tiddlywiki\";\n\tvar typeInfo = $tw.config.contentTypeInfo[type] || $tw.config.contentTypeInfo[\"text/plain\"],\n\t\tisBase64 = typeInfo.encoding === \"base64\",\n\t\tparts = [];\n\tparts.push(\"data:\");\n\tparts.push(type);\n\tparts.push(isBase64 ? \";base64\" : \"\");\n\tparts.push(\",\");\n\tparts.push(isBase64 ? text : encodeURIComponent(text));\n\treturn parts.join(\"\");\n};\n\n/*\nUseful for finding out the fully escaped CSS selector equivalent to a given tag. For example:\n\n$tw.utils.tagToCssSelector(\"$:/tags/Stylesheet\") --> tc-tagged-\\%24\\%3A\\%2Ftags\\%2FStylesheet\n*/\nexports.tagToCssSelector = function(tagName) {\n\treturn \"tc-tagged-\" + encodeURIComponent(tagName).replace(/[!\"#$%&'()*+,\\-./:;<=>?@[\\\\\\]^`{\\|}~,]/mg,function(c) {\n\t\treturn \"\\\\\" + c;\n\t});\n};\n\n/*\nIE does not have sign function\n*/\nexports.sign = Math.sign || function(x) {\n\tx = +x; // convert to a number\n\tif (x === 0 || isNaN(x)) {\n\t\treturn x;\n\t}\n\treturn x > 0 ? 1 : -1;\n};\n\n/*\nIE does not have an endsWith function\n*/\nexports.strEndsWith = function(str,ending,position) {\n\tif(str.endsWith) {\n\t\treturn str.endsWith(ending,position);\n\t} else {\n\t\tif (typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > str.length) {\n\t\t\tposition = str.length;\n\t\t}\n\t\tposition -= ending.length;\n\t\tvar lastIndex = str.indexOf(ending, position);\n\t\treturn lastIndex !== -1 && lastIndex === position;\n\t}\n};\n\n})();\n",
"type": "application/javascript",
"module-type": "utils"
},
"$:/core/modules/widgets/action-createtiddler.js": {
"title": "$:/core/modules/widgets/action-createtiddler.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/action-createtiddler.js\ntype: application/javascript\nmodule-type: widget\n\nAction widget to create a new tiddler with a unique name and specified fields.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar CreateTiddlerWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nCreateTiddlerWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nCreateTiddlerWidget.prototype.render = function(parent,nextSibling) {\n\tthis.computeAttributes();\n\tthis.execute();\n};\n\n/*\nCompute the internal state of the widget\n*/\nCreateTiddlerWidget.prototype.execute = function() {\n\tthis.actionBaseTitle = this.getAttribute(\"$basetitle\");\n\tthis.actionSaveTitle = this.getAttribute(\"$savetitle\");\n\tthis.actionTimestamp = this.getAttribute(\"$timestamp\",\"yes\") === \"yes\";\n};\n\n/*\nRefresh the widget by ensuring our attributes are up to date\n*/\nCreateTiddlerWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif($tw.utils.count(changedAttributes) > 0) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\n/*\nInvoke the action associated with this widget\n*/\nCreateTiddlerWidget.prototype.invokeAction = function(triggeringWidget,event) {\n\tvar title = this.wiki.generateNewTitle(this.actionBaseTitle),\n\t\tfields = {},\n\t\tcreationFields,\n\t\tmodificationFields;\n\t$tw.utils.each(this.attributes,function(attribute,name) {\n\t\tif(name.charAt(0) !== \"$\") {\n\t\t\tfields[name] = attribute;\n\t\t}\n\t});\n\tif(this.actionTimestamp) {\n\t\tcreationFields = this.wiki.getCreationFields();\n\t\tmodificationFields = this.wiki.getModificationFields();\n\t}\n\tvar tiddler = this.wiki.addTiddler(new $tw.Tiddler(creationFields,fields,modificationFields,{title: title}));\n\tif(this.actionSaveTitle) {\n\t\tthis.wiki.setTextReference(this.actionSaveTitle,title,this.getVariable(\"currentTiddler\"));\n\t}\n\treturn true; // Action was invoked\n};\n\nexports[\"action-createtiddler\"] = CreateTiddlerWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/action-deletefield.js": {
"title": "$:/core/modules/widgets/action-deletefield.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/action-deletefield.js\ntype: application/javascript\nmodule-type: widget\n\nAction widget to delete fields of a tiddler.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar DeleteFieldWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nDeleteFieldWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nDeleteFieldWidget.prototype.render = function(parent,nextSibling) {\n\tthis.computeAttributes();\n\tthis.execute();\n};\n\n/*\nCompute the internal state of the widget\n*/\nDeleteFieldWidget.prototype.execute = function() {\n\tthis.actionTiddler = this.getAttribute(\"$tiddler\",this.getVariable(\"currentTiddler\"));\n\tthis.actionField = this.getAttribute(\"$field\");\n};\n\n/*\nRefresh the widget by ensuring our attributes are up to date\n*/\nDeleteFieldWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes[\"$tiddler\"]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\n/*\nInvoke the action associated with this widget\n*/\nDeleteFieldWidget.prototype.invokeAction = function(triggeringWidget,event) {\n\tvar self = this,\n\t\ttiddler = this.wiki.getTiddler(self.actionTiddler),\n\t\tremoveFields = {},\n\t\thasChanged = false;\n\tif(this.actionField) {\n\t\tremoveFields[this.actionField] = undefined;\n\t\tif(this.actionField in tiddler.fields) {\n\t\t\thasChanged = true;\n\t\t}\n\t}\n\tif(tiddler) {\n\t\t$tw.utils.each(this.attributes,function(attribute,name) {\n\t\t\tif(name.charAt(0) !== \"$\" && name !== \"title\") {\n\t\t\t\tremoveFields[name] = undefined;\n\t\t\t\thasChanged = true;\n\t\t\t}\n\t\t});\n\t\tif(hasChanged) {\n\t\t\tthis.wiki.addTiddler(new $tw.Tiddler(this.wiki.getCreationFields(),tiddler,removeFields,this.wiki.getModificationFields()));\t\t\t\n\t\t}\n\t}\n\treturn true; // Action was invoked\n};\n\nexports[\"action-deletefield\"] = DeleteFieldWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/action-deletetiddler.js": {
"title": "$:/core/modules/widgets/action-deletetiddler.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/action-deletetiddler.js\ntype: application/javascript\nmodule-type: widget\n\nAction widget to delete a tiddler.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar DeleteTiddlerWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nDeleteTiddlerWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nDeleteTiddlerWidget.prototype.render = function(parent,nextSibling) {\n\tthis.computeAttributes();\n\tthis.execute();\n};\n\n/*\nCompute the internal state of the widget\n*/\nDeleteTiddlerWidget.prototype.execute = function() {\n\tthis.actionFilter = this.getAttribute(\"$filter\");\n\tthis.actionTiddler = this.getAttribute(\"$tiddler\");\n};\n\n/*\nRefresh the widget by ensuring our attributes are up to date\n*/\nDeleteTiddlerWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes[\"$filter\"] || changedAttributes[\"$tiddler\"]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\n/*\nInvoke the action associated with this widget\n*/\nDeleteTiddlerWidget.prototype.invokeAction = function(triggeringWidget,event) {\n\tvar tiddlers = [];\n\tif(this.actionFilter) {\n\t\ttiddlers = this.wiki.filterTiddlers(this.actionFilter,this);\n\t}\n\tif(this.actionTiddler) {\n\t\ttiddlers.push(this.actionTiddler);\n\t}\n\tfor(var t=0; t<tiddlers.length; t++) {\n\t\tthis.wiki.deleteTiddler(tiddlers[t]);\n\t}\n\treturn true; // Action was invoked\n};\n\nexports[\"action-deletetiddler\"] = DeleteTiddlerWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/action-listops.js": {
"title": "$:/core/modules/widgets/action-listops.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/action-listops.js\ntype: application/javascript\nmodule-type: widget\n\nAction widget to apply list operations to any tiddler field (defaults to the 'list' field of the current tiddler)\n\n\\*/\n(function() {\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\nvar ActionListopsWidget = function(parseTreeNode, options) {\n\tthis.initialise(parseTreeNode, options);\n};\n/**\n * Inherit from the base widget class\n */\nActionListopsWidget.prototype = new Widget();\n/**\n * Render this widget into the DOM\n */\nActionListopsWidget.prototype.render = function(parent, nextSibling) {\n\tthis.computeAttributes();\n\tthis.execute();\n};\n/**\n * Compute the internal state of the widget\n */\nActionListopsWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.target = this.getAttribute(\"$tiddler\", this.getVariable(\n\t\t\"currentTiddler\"));\n\tthis.filter = this.getAttribute(\"$filter\");\n\tthis.subfilter = this.getAttribute(\"$subfilter\");\n\tthis.listField = this.getAttribute(\"$field\", \"list\");\n\tthis.listIndex = this.getAttribute(\"$index\");\n\tthis.filtertags = this.getAttribute(\"$tags\");\n};\n/**\n * \tRefresh the widget by ensuring our attributes are up to date\n */\nActionListopsWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.$tiddler || changedAttributes.$filter ||\n\t\tchangedAttributes.$subfilter || changedAttributes.$field ||\n\t\tchangedAttributes.$index || changedAttributes.$tags) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n/**\n * \tInvoke the action associated with this widget\n */\nActionListopsWidget.prototype.invokeAction = function(triggeringWidget,\n\tevent) {\n\t//Apply the specified filters to the lists\n\tvar field = this.listField,\n\t\tindex,\n\t\ttype = \"!!\",\n\t\tlist = this.listField;\n\tif(this.listIndex) {\n\t\tfield = undefined;\n\t\tindex = this.listIndex;\n\t\ttype = \"##\";\n\t\tlist = this.listIndex;\n\t}\n\tif(this.filter) {\n\t\tthis.wiki.setText(this.target, field, index, $tw.utils.stringifyList(\n\t\t\tthis.wiki\n\t\t\t.filterTiddlers(this.filter, this)));\n\t}\n\tif(this.subfilter) {\n\t\tvar subfilter = \"[list[\" + this.target + type + list + \"]] \" + this.subfilter;\n\t\tthis.wiki.setText(this.target, field, index, $tw.utils.stringifyList(\n\t\t\tthis.wiki\n\t\t\t.filterTiddlers(subfilter, this)));\n\t}\n\tif(this.filtertags) {\n\t\tvar tiddler = this.wiki.getTiddler(this.target),\n\t\t\toldtags = tiddler ? (tiddler.fields.tags || []).slice(0) : [],\n\t\t\ttagfilter = \"[list[\" + this.target + \"!!tags]] \" + this.filtertags,\n\t\t\tnewtags = this.wiki.filterTiddlers(tagfilter,this);\n\t\tif($tw.utils.stringifyList(oldtags.sort()) !== $tw.utils.stringifyList(newtags.sort())) {\n\t\t\tthis.wiki.setText(this.target,\"tags\",undefined,$tw.utils.stringifyList(newtags));\t\t\t\n\t\t}\n\t}\n\treturn true; // Action was invoked\n};\n\nexports[\"action-listops\"] = ActionListopsWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/action-navigate.js": {
"title": "$:/core/modules/widgets/action-navigate.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/action-navigate.js\ntype: application/javascript\nmodule-type: widget\n\nAction widget to navigate to a tiddler\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar NavigateWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nNavigateWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nNavigateWidget.prototype.render = function(parent,nextSibling) {\n\tthis.computeAttributes();\n\tthis.execute();\n};\n\n/*\nCompute the internal state of the widget\n*/\nNavigateWidget.prototype.execute = function() {\n\tthis.actionTo = this.getAttribute(\"$to\");\n\tthis.actionScroll = this.getAttribute(\"$scroll\");\n};\n\n/*\nRefresh the widget by ensuring our attributes are up to date\n*/\nNavigateWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes[\"$to\"] || changedAttributes[\"$scroll\"]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\n/*\nInvoke the action associated with this widget\n*/\nNavigateWidget.prototype.invokeAction = function(triggeringWidget,event) {\n\tevent = event || {};\n\tvar bounds = triggeringWidget && triggeringWidget.getBoundingClientRect && triggeringWidget.getBoundingClientRect(),\n\t\tsuppressNavigation = event.metaKey || event.ctrlKey || (event.button === 1);\n\tif(this.actionScroll === \"yes\") {\n\t\tsuppressNavigation = false;\n\t} else if(this.actionScroll === \"no\") {\n\t\tsuppressNavigation = true;\n\t}\n\tthis.dispatchEvent({\n\t\ttype: \"tm-navigate\",\n\t\tnavigateTo: this.actionTo === undefined ? this.getVariable(\"currentTiddler\") : this.actionTo,\n\t\tnavigateFromTitle: this.getVariable(\"storyTiddler\"),\n\t\tnavigateFromNode: triggeringWidget,\n\t\tnavigateFromClientRect: bounds && { top: bounds.top, left: bounds.left, width: bounds.width, right: bounds.right, bottom: bounds.bottom, height: bounds.height\n\t\t},\n\t\tnavigateSuppressNavigation: suppressNavigation\n\t});\n\treturn true; // Action was invoked\n};\n\nexports[\"action-navigate\"] = NavigateWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/action-sendmessage.js": {
"title": "$:/core/modules/widgets/action-sendmessage.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/action-sendmessage.js\ntype: application/javascript\nmodule-type: widget\n\nAction widget to send a message\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar SendMessageWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nSendMessageWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nSendMessageWidget.prototype.render = function(parent,nextSibling) {\n\tthis.computeAttributes();\n\tthis.execute();\n};\n\n/*\nCompute the internal state of the widget\n*/\nSendMessageWidget.prototype.execute = function() {\n\tthis.actionMessage = this.getAttribute(\"$message\");\n\tthis.actionParam = this.getAttribute(\"$param\");\n\tthis.actionName = this.getAttribute(\"$name\");\n\tthis.actionValue = this.getAttribute(\"$value\",\"\");\n};\n\n/*\nRefresh the widget by ensuring our attributes are up to date\n*/\nSendMessageWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(Object.keys(changedAttributes).length) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\n/*\nInvoke the action associated with this widget\n*/\nSendMessageWidget.prototype.invokeAction = function(triggeringWidget,event) {\n\t// Get the string parameter\n\tvar param = this.actionParam;\n\t// Assemble the attributes as a hashmap\n\tvar paramObject = Object.create(null);\n\tvar count = 0;\n\t$tw.utils.each(this.attributes,function(attribute,name) {\n\t\tif(name.charAt(0) !== \"$\") {\n\t\t\tparamObject[name] = attribute;\n\t\t\tcount++;\n\t\t}\n\t});\n\t// Add name/value pair if present\n\tif(this.actionName) {\n\t\tparamObject[this.actionName] = this.actionValue;\n\t}\n\t// Dispatch the message\n\tthis.dispatchEvent({\n\t\ttype: this.actionMessage,\n\t\tparam: param,\n\t\tparamObject: paramObject,\n\t\ttiddlerTitle: this.getVariable(\"currentTiddler\"),\n\t\tnavigateFromTitle: this.getVariable(\"storyTiddler\"),\n\t\tevent: event\n\t});\n\treturn true; // Action was invoked\n};\n\nexports[\"action-sendmessage\"] = SendMessageWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/action-setfield.js": {
"title": "$:/core/modules/widgets/action-setfield.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/action-setfield.js\ntype: application/javascript\nmodule-type: widget\n\nAction widget to set a single field or index on a tiddler.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar SetFieldWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nSetFieldWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nSetFieldWidget.prototype.render = function(parent,nextSibling) {\n\tthis.computeAttributes();\n\tthis.execute();\n};\n\n/*\nCompute the internal state of the widget\n*/\nSetFieldWidget.prototype.execute = function() {\n\tthis.actionTiddler = this.getAttribute(\"$tiddler\",this.getVariable(\"currentTiddler\"));\n\tthis.actionField = this.getAttribute(\"$field\");\n\tthis.actionIndex = this.getAttribute(\"$index\");\n\tthis.actionValue = this.getAttribute(\"$value\");\n\tthis.actionTimestamp = this.getAttribute(\"$timestamp\",\"yes\") === \"yes\";\n};\n\n/*\nRefresh the widget by ensuring our attributes are up to date\n*/\nSetFieldWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes[\"$tiddler\"] || changedAttributes[\"$field\"] || changedAttributes[\"$index\"] || changedAttributes[\"$value\"]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\n/*\nInvoke the action associated with this widget\n*/\nSetFieldWidget.prototype.invokeAction = function(triggeringWidget,event) {\n\tvar self = this,\n\t\toptions = {};\n\toptions.suppressTimestamp = !this.actionTimestamp;\n\tif((typeof this.actionField == \"string\") || (typeof this.actionIndex == \"string\") || (typeof this.actionValue == \"string\")) {\n\t\tthis.wiki.setText(this.actionTiddler,this.actionField,this.actionIndex,this.actionValue,options);\n\t}\n\t$tw.utils.each(this.attributes,function(attribute,name) {\n\t\tif(name.charAt(0) !== \"$\") {\n\t\t\tself.wiki.setText(self.actionTiddler,name,undefined,attribute,options);\n\t\t}\n\t});\n\treturn true; // Action was invoked\n};\n\nexports[\"action-setfield\"] = SetFieldWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/browse.js": {
"title": "$:/core/modules/widgets/browse.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/browse.js\ntype: application/javascript\nmodule-type: widget\n\nBrowse widget for browsing for files to import\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar BrowseWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nBrowseWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nBrowseWidget.prototype.render = function(parent,nextSibling) {\n\tvar self = this;\n\t// Remember parent\n\tthis.parentDomNode = parent;\n\t// Compute attributes and execute state\n\tthis.computeAttributes();\n\tthis.execute();\n\t// Create element\n\tvar domNode = this.document.createElement(\"input\");\n\tdomNode.setAttribute(\"type\",\"file\");\n\tif(this.browseMultiple) {\n\t\tdomNode.setAttribute(\"multiple\",\"multiple\");\n\t}\n\tif(this.tooltip) {\n\t\tdomNode.setAttribute(\"title\",this.tooltip);\n\t}\n\t// Nw.js supports \"nwsaveas\" to force a \"save as\" dialogue that allows a new or existing file to be selected\n\tif(this.nwsaveas) {\n\t\tdomNode.setAttribute(\"nwsaveas\",this.nwsaveas);\n\t}\n\t// Nw.js supports \"webkitdirectory\" and \"nwdirectory\" to allow a directory to be selected\n\tif(this.webkitdirectory) {\n\t\tdomNode.setAttribute(\"webkitdirectory\",this.webkitdirectory);\n\t}\n\tif(this.nwdirectory) {\n\t\tdomNode.setAttribute(\"nwdirectory\",this.nwdirectory);\n\t}\n\t// Add a click event handler\n\tdomNode.addEventListener(\"change\",function (event) {\n\t\tif(self.message) {\n\t\t\tself.dispatchEvent({type: self.message, param: self.param, files: event.target.files});\n\t\t} else {\n\t\t\tself.wiki.readFiles(event.target.files,{\n\t\t\t\tcallback: function(tiddlerFieldsArray) {\n\t\t\t\t\tself.dispatchEvent({type: \"tm-import-tiddlers\", param: JSON.stringify(tiddlerFieldsArray)});\n\t\t\t\t},\n\t\t\t\tdeserializer: self.deserializer\n\t\t\t});\n\t\t}\n\t\treturn false;\n\t},false);\n\t// Insert element\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.renderChildren(domNode,null);\n\tthis.domNodes.push(domNode);\n};\n\n/*\nCompute the internal state of the widget\n*/\nBrowseWidget.prototype.execute = function() {\n\tthis.browseMultiple = this.getAttribute(\"multiple\");\n\tthis.deserializer = this.getAttribute(\"deserializer\");\n\tthis.message = this.getAttribute(\"message\");\n\tthis.param = this.getAttribute(\"param\");\n\tthis.tooltip = this.getAttribute(\"tooltip\");\n\tthis.nwsaveas = this.getAttribute(\"nwsaveas\");\n\tthis.webkitdirectory = this.getAttribute(\"webkitdirectory\");\n\tthis.nwdirectory = this.getAttribute(\"nwdirectory\");\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nBrowseWidget.prototype.refresh = function(changedTiddlers) {\n\treturn false;\n};\n\nexports.browse = BrowseWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/button.js": {
"title": "$:/core/modules/widgets/button.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/button.js\ntype: application/javascript\nmodule-type: widget\n\nButton widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar ButtonWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nButtonWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nButtonWidget.prototype.render = function(parent,nextSibling) {\n\tvar self = this;\n\t// Remember parent\n\tthis.parentDomNode = parent;\n\t// Compute attributes and execute state\n\tthis.computeAttributes();\n\tthis.execute();\n\t// Create element\n\tvar tag = \"button\";\n\tif(this.buttonTag && $tw.config.htmlUnsafeElements.indexOf(this.buttonTag) === -1) {\n\t\ttag = this.buttonTag;\n\t}\n\tvar domNode = this.document.createElement(tag);\n\t// Assign classes\n\tvar classes = this[\"class\"].split(\" \") || [],\n\t\tisPoppedUp = (this.popup || this.popupTitle) && this.isPoppedUp();\n\tif(this.selectedClass) {\n\t\tif((this.set || this.setTitle) && this.setTo && this.isSelected()) {\n\t\t\t$tw.utils.pushTop(classes,this.selectedClass.split(\" \"));\n\t\t}\n\t\tif(isPoppedUp) {\n\t\t\t$tw.utils.pushTop(classes,this.selectedClass.split(\" \"));\n\t\t}\n\t}\n\tif(isPoppedUp) {\n\t\t$tw.utils.pushTop(classes,\"tc-popup-handle\");\n\t}\n\tdomNode.className = classes.join(\" \");\n\t// Assign other attributes\n\tif(this.style) {\n\t\tdomNode.setAttribute(\"style\",this.style);\n\t}\n\tif(this.tooltip) {\n\t\tdomNode.setAttribute(\"title\",this.tooltip);\n\t}\n\tif(this[\"aria-label\"]) {\n\t\tdomNode.setAttribute(\"aria-label\",this[\"aria-label\"]);\n\t}\n\t// Add a click event handler\n\tdomNode.addEventListener(\"click\",function (event) {\n\t\tvar handled = false;\n\t\tif(self.invokeActions(self,event)) {\n\t\t\thandled = true;\n\t\t}\n\t\tif(self.to) {\n\t\t\tself.navigateTo(event);\n\t\t\thandled = true;\n\t\t}\n\t\tif(self.message) {\n\t\t\tself.dispatchMessage(event);\n\t\t\thandled = true;\n\t\t}\n\t\tif(self.popup || self.popupTitle) {\n\t\t\tself.triggerPopup(event);\n\t\t\thandled = true;\n\t\t}\n\t\tif(self.set || self.setTitle) {\n\t\t\tself.setTiddler();\n\t\t\thandled = true;\n\t\t}\n\t\tif(self.actions) {\n\t\t\tself.invokeActionString(self.actions,self,event);\n\t\t}\n\t\tif(handled) {\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\t\t}\n\t\treturn handled;\n\t},false);\n\t// Make it draggable if required\n\tif(this.dragTiddler || this.dragFilter) {\n\t\t$tw.utils.makeDraggable({\n\t\t\tdomNode: domNode,\n\t\t\tdragTiddlerFn: function() {return self.dragTiddler;},\n\t\t\tdragFilterFn: function() {return self.dragFilter;},\n\t\t\twidget: this\n\t\t});\n\t}\n\t// Insert element\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.renderChildren(domNode,null);\n\tthis.domNodes.push(domNode);\n};\n\n/*\nWe don't allow actions to propagate because we trigger actions ourselves\n*/\nButtonWidget.prototype.allowActionPropagation = function() {\n\treturn false;\n};\n\nButtonWidget.prototype.getBoundingClientRect = function() {\n\treturn this.domNodes[0].getBoundingClientRect();\n};\n\nButtonWidget.prototype.isSelected = function() {\n return this.setTitle ? (this.setField ? this.wiki.getTiddler(this.setTitle).getFieldString(this.setField) === this.setTo :\n\t\t(this.setIndex ? this.wiki.extractTiddlerDataItem(this.setTitle,this.setIndex) === this.setTo :\n\t\t\tthis.wiki.getTiddlerText(this.setTitle))) || this.defaultSetValue || this.getVariable(\"currentTiddler\") :\n\t\tthis.wiki.getTextReference(this.set,this.defaultSetValue,this.getVariable(\"currentTiddler\")) === this.setTo;\n};\n\nButtonWidget.prototype.isPoppedUp = function() {\n\tvar tiddler = this.popupTitle ? this.wiki.getTiddler(this.popupTitle) : this.wiki.getTiddler(this.popup);\n\tvar result = tiddler && tiddler.fields.text ? $tw.popup.readPopupState(tiddler.fields.text) : false;\n\treturn result;\n};\n\nButtonWidget.prototype.navigateTo = function(event) {\n\tvar bounds = this.getBoundingClientRect();\n\tthis.dispatchEvent({\n\t\ttype: \"tm-navigate\",\n\t\tnavigateTo: this.to,\n\t\tnavigateFromTitle: this.getVariable(\"storyTiddler\"),\n\t\tnavigateFromNode: this,\n\t\tnavigateFromClientRect: { top: bounds.top, left: bounds.left, width: bounds.width, right: bounds.right, bottom: bounds.bottom, height: bounds.height\n\t\t},\n\t\tnavigateSuppressNavigation: event.metaKey || event.ctrlKey || (event.button === 1),\n\t\tevent: event\n\t});\n};\n\nButtonWidget.prototype.dispatchMessage = function(event) {\n\tthis.dispatchEvent({type: this.message, param: this.param, tiddlerTitle: this.getVariable(\"currentTiddler\"), event: event});\n};\n\nButtonWidget.prototype.triggerPopup = function(event) {\n\tif(this.popupTitle) {\n\t\t$tw.popup.triggerPopup({\n\t\t\tdomNode: this.domNodes[0],\n\t\t\ttitle: this.popupTitle,\n\t\t\twiki: this.wiki,\n\t\t\tnoStateReference: true\n\t\t});\n\t} else {\n\t\t$tw.popup.triggerPopup({\n\t\t\tdomNode: this.domNodes[0],\n\t\t\ttitle: this.popup,\n\t\t\twiki: this.wiki\n\t\t});\n\t}\n};\n\nButtonWidget.prototype.setTiddler = function() {\n\tif(this.setTitle) {\n\t\tthis.setField ? this.wiki.setText(this.setTitle,this.setField,undefined,this.setTo) :\n\t\t\t\t(this.setIndex ? this.wiki.setText(this.setTitle,undefined,this.setIndex,this.setTo) :\n\t\t\t\tthis.wiki.setText(this.setTitle,\"text\",undefined,this.setTo));\n\t} else {\n\t\tthis.wiki.setTextReference(this.set,this.setTo,this.getVariable(\"currentTiddler\"));\n\t}\n};\n\n/*\nCompute the internal state of the widget\n*/\nButtonWidget.prototype.execute = function() {\n\t// Get attributes\n\tthis.actions = this.getAttribute(\"actions\");\n\tthis.to = this.getAttribute(\"to\");\n\tthis.message = this.getAttribute(\"message\");\n\tthis.param = this.getAttribute(\"param\");\n\tthis.set = this.getAttribute(\"set\");\n\tthis.setTo = this.getAttribute(\"setTo\");\n\tthis.popup = this.getAttribute(\"popup\");\n\tthis.hover = this.getAttribute(\"hover\");\n\tthis[\"class\"] = this.getAttribute(\"class\",\"\");\n\tthis[\"aria-label\"] = this.getAttribute(\"aria-label\");\n\tthis.tooltip = this.getAttribute(\"tooltip\");\n\tthis.style = this.getAttribute(\"style\");\n\tthis.selectedClass = this.getAttribute(\"selectedClass\");\n\tthis.defaultSetValue = this.getAttribute(\"default\",\"\");\n\tthis.buttonTag = this.getAttribute(\"tag\");\n\tthis.dragTiddler = this.getAttribute(\"dragTiddler\");\n\tthis.dragFilter = this.getAttribute(\"dragFilter\");\n\tthis.setTitle = this.getAttribute(\"setTitle\");\n\tthis.setField = this.getAttribute(\"setField\");\n\tthis.setIndex = this.getAttribute(\"setIndex\");\n\tthis.popupTitle = this.getAttribute(\"popupTitle\");\n\t// Make child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nButtonWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.to || changedAttributes.message || changedAttributes.param || changedAttributes.set || changedAttributes.setTo || changedAttributes.popup || changedAttributes.hover || changedAttributes[\"class\"] || changedAttributes.selectedClass || changedAttributes.style || changedAttributes.dragFilter || changedAttributes.dragTiddler || (this.set && changedTiddlers[this.set]) || (this.popup && changedTiddlers[this.popup]) || (this.popupTitle && changedTiddlers[this.popupTitle]) || changedAttributes.setTitle || changedAttributes.setField || changedAttributes.setIndex || changedAttributes.popupTitle) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\nexports.button = ButtonWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/checkbox.js": {
"title": "$:/core/modules/widgets/checkbox.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/checkbox.js\ntype: application/javascript\nmodule-type: widget\n\nCheckbox widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar CheckboxWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nCheckboxWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nCheckboxWidget.prototype.render = function(parent,nextSibling) {\n\t// Save the parent dom node\n\tthis.parentDomNode = parent;\n\t// Compute our attributes\n\tthis.computeAttributes();\n\t// Execute our logic\n\tthis.execute();\n\t// Create our elements\n\tthis.labelDomNode = this.document.createElement(\"label\");\n\tthis.labelDomNode.setAttribute(\"class\",this.checkboxClass);\n\tthis.inputDomNode = this.document.createElement(\"input\");\n\tthis.inputDomNode.setAttribute(\"type\",\"checkbox\");\n\tif(this.getValue()) {\n\t\tthis.inputDomNode.setAttribute(\"checked\",\"true\");\n\t}\n\tthis.labelDomNode.appendChild(this.inputDomNode);\n\tthis.spanDomNode = this.document.createElement(\"span\");\n\tthis.labelDomNode.appendChild(this.spanDomNode);\n\t// Add a click event handler\n\t$tw.utils.addEventListeners(this.inputDomNode,[\n\t\t{name: \"change\", handlerObject: this, handlerMethod: \"handleChangeEvent\"}\n\t]);\n\t// Insert the label into the DOM and render any children\n\tparent.insertBefore(this.labelDomNode,nextSibling);\n\tthis.renderChildren(this.spanDomNode,null);\n\tthis.domNodes.push(this.labelDomNode);\n};\n\nCheckboxWidget.prototype.getValue = function() {\n\tvar tiddler = this.wiki.getTiddler(this.checkboxTitle);\n\tif(tiddler) {\n\t\tif(this.checkboxTag) {\n\t\t\tif(this.checkboxInvertTag) {\n\t\t\t\treturn !tiddler.hasTag(this.checkboxTag);\n\t\t\t} else {\n\t\t\t\treturn tiddler.hasTag(this.checkboxTag);\n\t\t\t}\n\t\t}\n\t\tif(this.checkboxField) {\n\t\t\tvar value;\n\t\t\tif($tw.utils.hop(tiddler.fields,this.checkboxField)) {\n\t\t\t\tvalue = tiddler.fields[this.checkboxField] || \"\";\n\t\t\t} else {\n\t\t\t\tvalue = this.checkboxDefault || \"\";\n\t\t\t}\n\t\t\tif(value === this.checkboxChecked) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif(value === this.checkboxUnchecked) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\tif(this.checkboxIndex) {\n\t\t\tvar value = this.wiki.extractTiddlerDataItem(tiddler,this.checkboxIndex,this.checkboxDefault || \"\");\n\t\t\tif(value === this.checkboxChecked) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif(value === this.checkboxUnchecked) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t} else {\n\t\tif(this.checkboxTag) {\n\t\t\treturn false;\n\t\t}\n\t\tif(this.checkboxField) {\n\t\t\tif(this.checkboxDefault === this.checkboxChecked) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif(this.checkboxDefault === this.checkboxUnchecked) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t}\n\treturn false;\n};\n\nCheckboxWidget.prototype.handleChangeEvent = function(event) {\n\tvar checked = this.inputDomNode.checked,\n\t\ttiddler = this.wiki.getTiddler(this.checkboxTitle),\n\t\tfallbackFields = {text: \"\"},\n\t\tnewFields = {title: this.checkboxTitle},\n\t\thasChanged = false,\n\t\ttagCheck = false,\n\t\thasTag = tiddler && tiddler.hasTag(this.checkboxTag),\n\t\tvalue = checked ? this.checkboxChecked : this.checkboxUnchecked;\n\tif(this.checkboxTag && this.checkboxInvertTag === \"yes\") {\n\t\ttagCheck = hasTag === checked;\n\t} else {\n\t\ttagCheck = hasTag !== checked;\n\t}\n\t// Set the tag if specified\n\tif(this.checkboxTag && (!tiddler || tagCheck)) {\n\t\tnewFields.tags = tiddler ? (tiddler.fields.tags || []).slice(0) : [];\n\t\tvar pos = newFields.tags.indexOf(this.checkboxTag);\n\t\tif(pos !== -1) {\n\t\t\tnewFields.tags.splice(pos,1);\n\t\t}\n\t\tif(this.checkboxInvertTag === \"yes\" && !checked) {\n\t\t\tnewFields.tags.push(this.checkboxTag);\n\t\t} else if(this.checkboxInvertTag !== \"yes\" && checked) {\n\t\t\tnewFields.tags.push(this.checkboxTag);\n\t\t}\n\t\thasChanged = true;\n\t}\n\t// Set the field if specified\n\tif(this.checkboxField) {\n\t\tif(!tiddler || tiddler.fields[this.checkboxField] !== value) {\n\t\t\tnewFields[this.checkboxField] = value;\n\t\t\thasChanged = true;\n\t\t}\n\t}\n\t// Set the index if specified\n\tif(this.checkboxIndex) {\n\t\tvar indexValue = this.wiki.extractTiddlerDataItem(this.checkboxTitle,this.checkboxIndex);\n\t\tif(!tiddler || indexValue !== value) {\n\t\t\thasChanged = true;\n\t\t}\n\t}\n\tif(hasChanged) {\n\t\tif(this.checkboxIndex) {\n\t\t\tthis.wiki.setText(this.checkboxTitle,\"\",this.checkboxIndex,value);\n\t\t} else {\n\t\t\tthis.wiki.addTiddler(new $tw.Tiddler(this.wiki.getCreationFields(),fallbackFields,tiddler,newFields,this.wiki.getModificationFields()));\n\t\t}\n\t}\n\t// Trigger actions\n\tif(this.checkboxActions) {\n\t\tthis.invokeActionString(this.checkboxActions,this,event);\n\t}\n\tif(this.checkboxUncheckActions && !checked) {\n\t\tthis.invokeActionString(this.checkboxUncheckActions,this,event);\n\t}\n};\n\n/*\nCompute the internal state of the widget\n*/\nCheckboxWidget.prototype.execute = function() {\n\t// Get the parameters from the attributes\n\tthis.checkboxActions = this.getAttribute(\"actions\");\n\tthis.checkboxUncheckActions = this.getAttribute(\"uncheckactions\");\n\tthis.checkboxTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\tthis.checkboxTag = this.getAttribute(\"tag\");\n\tthis.checkboxField = this.getAttribute(\"field\");\n\tthis.checkboxIndex = this.getAttribute(\"index\");\n\tthis.checkboxChecked = this.getAttribute(\"checked\");\n\tthis.checkboxUnchecked = this.getAttribute(\"unchecked\");\n\tthis.checkboxDefault = this.getAttribute(\"default\");\n\tthis.checkboxClass = this.getAttribute(\"class\",\"\");\n\tthis.checkboxInvertTag = this.getAttribute(\"invertTag\",\"\");\n\t// Make the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nCheckboxWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.tiddler || changedAttributes.tag || changedAttributes.invertTag || changedAttributes.field || changedAttributes.index || changedAttributes.checked || changedAttributes.unchecked || changedAttributes[\"default\"] || changedAttributes[\"class\"]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\tvar refreshed = false;\n\t\tif(changedTiddlers[this.checkboxTitle]) {\n\t\t\tthis.inputDomNode.checked = this.getValue();\n\t\t\trefreshed = true;\n\t\t}\n\t\treturn this.refreshChildren(changedTiddlers) || refreshed;\n\t}\n};\n\nexports.checkbox = CheckboxWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/codeblock.js": {
"title": "$:/core/modules/widgets/codeblock.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/codeblock.js\ntype: application/javascript\nmodule-type: widget\n\nCode block node widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar CodeBlockWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nCodeBlockWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nCodeBlockWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tvar codeNode = this.document.createElement(\"code\"),\n\t\tdomNode = this.document.createElement(\"pre\");\n\tcodeNode.appendChild(this.document.createTextNode(this.getAttribute(\"code\")));\n\tdomNode.appendChild(codeNode);\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.domNodes.push(domNode);\n\tif(this.postRender) {\n\t\tthis.postRender();\n\t}\n};\n\n/*\nCompute the internal state of the widget\n*/\nCodeBlockWidget.prototype.execute = function() {\n\tthis.language = this.getAttribute(\"language\");\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nCodeBlockWidget.prototype.refresh = function(changedTiddlers) {\n\treturn false;\n};\n\nexports.codeblock = CodeBlockWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/count.js": {
"title": "$:/core/modules/widgets/count.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/count.js\ntype: application/javascript\nmodule-type: widget\n\nCount widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar CountWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nCountWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nCountWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tvar textNode = this.document.createTextNode(this.currentCount);\n\tparent.insertBefore(textNode,nextSibling);\n\tthis.domNodes.push(textNode);\n};\n\n/*\nCompute the internal state of the widget\n*/\nCountWidget.prototype.execute = function() {\n\t// Get parameters from our attributes\n\tthis.filter = this.getAttribute(\"filter\");\n\t// Execute the filter\n\tif(this.filter) {\n\t\tthis.currentCount = this.wiki.filterTiddlers(this.filter,this).length;\n\t} else {\n\t\tthis.currentCount = undefined;\n\t}\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nCountWidget.prototype.refresh = function(changedTiddlers) {\n\t// Re-execute the filter to get the count\n\tthis.computeAttributes();\n\tvar oldCount = this.currentCount;\n\tthis.execute();\n\tif(this.currentCount !== oldCount) {\n\t\t// Regenerate and rerender the widget and replace the existing DOM node\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn false;\n\t}\n\n};\n\nexports.count = CountWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/diff-text.js": {
"title": "$:/core/modules/widgets/diff-text.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/diff-text.js\ntype: application/javascript\nmodule-type: widget\n\nWidget to display a diff between two texts\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget,\n\tdmp = require(\"$:/core/modules/utils/diff-match-patch/diff_match_patch.js\");\n\nvar DiffTextWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nDiffTextWidget.prototype = new Widget();\n\nDiffTextWidget.prototype.invisibleCharacters = {\n\t\"\\n\": \"↩︎\\n\",\n\t\"\\r\": \"⇠\",\n\t\"\\t\": \"⇥\\t\"\n};\n\n/*\nRender this widget into the DOM\n*/\nDiffTextWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\t// Create the diff\n\tvar dmpObject = new dmp.diff_match_patch(),\n\t\tdiffs = dmpObject.diff_main(this.getAttribute(\"source\"),this.getAttribute(\"dest\"));\n\t// Apply required cleanup\n\tswitch(this.getAttribute(\"cleanup\",\"semantic\")) {\n\t\tcase \"none\":\n\t\t\t// No cleanup\n\t\t\tbreak;\n\t\tcase \"efficiency\":\n\t\t\tdmpObject.diff_cleanupEfficiency(diffs);\n\t\t\tbreak;\n\t\tdefault: // case \"semantic\"\n\t\t\tdmpObject.diff_cleanupSemantic(diffs);\n\t\t\tbreak;\n\t}\n\t// Create the elements\n\tvar domContainer = this.document.createElement(\"div\"), \n\t\tdomDiff = this.createDiffDom(diffs);\n\tparent.insertBefore(domContainer,nextSibling);\n\t// Set variables\n\tthis.setVariable(\"diff-count\",diffs.reduce(function(acc,diff) {\n\t\tif(diff[0] !== dmp.DIFF_EQUAL) {\n\t\t\tacc++;\n\t\t}\n\t\treturn acc;\n\t},0).toString());\n\t// Render child widgets\n\tthis.renderChildren(domContainer,null);\n\t// Render the diff\n\tdomContainer.appendChild(domDiff);\n\t// Save our container\n\tthis.domNodes.push(domContainer);\n};\n\n/*\nCreate DOM elements representing a list of diffs\n*/\nDiffTextWidget.prototype.createDiffDom = function(diffs) {\n\tvar self = this;\n\t// Create the element and assign the attributes\n\tvar domPre = this.document.createElement(\"pre\"),\n\t\tdomCode = this.document.createElement(\"code\");\n\t$tw.utils.each(diffs,function(diff) {\n\t\tvar tag = diff[0] === dmp.DIFF_INSERT ? \"ins\" : (diff[0] === dmp.DIFF_DELETE ? \"del\" : \"span\"),\n\t\t\tclassName = diff[0] === dmp.DIFF_INSERT ? \"tc-diff-insert\" : (diff[0] === dmp.DIFF_DELETE ? \"tc-diff-delete\" : \"tc-diff-equal\"),\n\t\t\tdom = self.document.createElement(tag),\n\t\t\ttext = diff[1],\n\t\t\tcurrPos = 0,\n\t\t\tre = /([\\x00-\\x1F])/mg,\n\t\t\tmatch = re.exec(text),\n\t\t\tspan,\n\t\t\tprintable;\n\t\tdom.className = className;\n\t\twhile(match) {\n\t\t\tif(currPos < match.index) {\n\t\t\t\tdom.appendChild(self.document.createTextNode(text.slice(currPos,match.index)));\n\t\t\t}\n\t\t\tspan = self.document.createElement(\"span\");\n\t\t\tspan.className = \"tc-diff-invisible\";\n\t\t\tprintable = self.invisibleCharacters[match[0]] || (\"[0x\" + match[0].charCodeAt(0).toString(16) + \"]\");\n\t\t\tspan.appendChild(self.document.createTextNode(printable));\n\t\t\tdom.appendChild(span);\n\t\t\tcurrPos = match.index + match[0].length;\n\t\t\tmatch = re.exec(text);\n\t\t}\n\t\tif(currPos < text.length) {\n\t\t\tdom.appendChild(self.document.createTextNode(text.slice(currPos)));\n\t\t}\n\t\tdomCode.appendChild(dom);\n\t});\n\tdomPre.appendChild(domCode);\n\treturn domPre;\n};\n\n/*\nCompute the internal state of the widget\n*/\nDiffTextWidget.prototype.execute = function() {\n\t// Make child widgets\n\tvar parseTreeNodes;\n\tif(this.parseTreeNode && this.parseTreeNode.children && this.parseTreeNode.children.length > 0) {\n\t\tparseTreeNodes = this.parseTreeNode.children;\n\t} else {\n\t\tparseTreeNodes = [{\n\t\t\ttype: \"transclude\",\n\t\t\tattributes: {\n\t\t\t\ttiddler: {type: \"string\", value: \"$:/language/Diffs/CountMessage\"}\n\t\t\t}\n\t\t}];\n\t}\n\tthis.makeChildWidgets(parseTreeNodes);\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nDiffTextWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.source || changedAttributes.dest || changedAttributes.cleanup) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\n\t}\n};\n\nexports[\"diff-text\"] = DiffTextWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/draggable.js": {
"title": "$:/core/modules/widgets/draggable.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/draggable.js\ntype: application/javascript\nmodule-type: widget\n\nDraggable widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar DraggableWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nDraggableWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nDraggableWidget.prototype.render = function(parent,nextSibling) {\n\tvar self = this;\n\t// Save the parent dom node\n\tthis.parentDomNode = parent;\n\t// Compute our attributes\n\tthis.computeAttributes();\n\t// Execute our logic\n\tthis.execute();\n\t// Sanitise the specified tag\n\tvar tag = this.draggableTag;\n\tif($tw.config.htmlUnsafeElements.indexOf(tag) !== -1) {\n\t\ttag = \"div\";\n\t}\n\t// Create our element\n\tvar domNode = this.document.createElement(tag);\n\t// Assign classes\n\tvar classes = [\"tc-draggable\"];\n\tif(this.draggableClasses) {\n\t\tclasses.push(this.draggableClasses);\n\t}\n\tdomNode.setAttribute(\"class\",classes.join(\" \"));\n\t// Add event handlers\n\t$tw.utils.makeDraggable({\n\t\tdomNode: domNode,\n\t\tdragTiddlerFn: function() {return self.getAttribute(\"tiddler\");},\n\t\tdragFilterFn: function() {return self.getAttribute(\"filter\");},\n\t\tstartActions: self.startActions,\n\t\tendActions: self.endActions,\n\t\twidget: this\n\t});\n\t// Insert the link into the DOM and render any children\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.renderChildren(domNode,null);\n\tthis.domNodes.push(domNode);\n};\n\n/*\nCompute the internal state of the widget\n*/\nDraggableWidget.prototype.execute = function() {\n\t// Pick up our attributes\n\tthis.draggableTag = this.getAttribute(\"tag\",\"div\");\n\tthis.draggableClasses = this.getAttribute(\"class\");\n\tthis.startActions = this.getAttribute(\"startactions\");\n\tthis.endActions = this.getAttribute(\"endactions\");\n\t// Make the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nDraggableWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedTiddlers.tag || changedTiddlers[\"class\"]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\nexports.draggable = DraggableWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/droppable.js": {
"title": "$:/core/modules/widgets/droppable.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/droppable.js\ntype: application/javascript\nmodule-type: widget\n\nDroppable widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar DroppableWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nDroppableWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nDroppableWidget.prototype.render = function(parent,nextSibling) {\n\tvar self = this;\n\t// Remember parent\n\tthis.parentDomNode = parent;\n\t// Compute attributes and execute state\n\tthis.computeAttributes();\n\tthis.execute();\n\tvar tag = this.parseTreeNode.isBlock ? \"div\" : \"span\";\n\tif(this.droppableTag && $tw.config.htmlUnsafeElements.indexOf(this.droppableTag) === -1) {\n\t\ttag = this.droppableTag;\n\t}\n\t// Create element and assign classes\n\tvar domNode = this.document.createElement(tag),\n\t\tclasses = (this[\"class\"] || \"\").split(\" \");\n\tclasses.push(\"tc-droppable\");\n\tdomNode.className = classes.join(\" \");\n\t// Add event handlers\n\t$tw.utils.addEventListeners(domNode,[\n\t\t{name: \"dragenter\", handlerObject: this, handlerMethod: \"handleDragEnterEvent\"},\n\t\t{name: \"dragover\", handlerObject: this, handlerMethod: \"handleDragOverEvent\"},\n\t\t{name: \"dragleave\", handlerObject: this, handlerMethod: \"handleDragLeaveEvent\"},\n\t\t{name: \"drop\", handlerObject: this, handlerMethod: \"handleDropEvent\"}\n\t]);\n\t// Insert element\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.renderChildren(domNode,null);\n\tthis.domNodes.push(domNode);\n\t// Stack of outstanding enter/leave events\n\tthis.currentlyEntered = [];\n};\n\nDroppableWidget.prototype.enterDrag = function(event) {\n\tif(this.currentlyEntered.indexOf(event.target) === -1) {\n\t\tthis.currentlyEntered.push(event.target);\n\t}\n\t// If we're entering for the first time we need to apply highlighting\n\t$tw.utils.addClass(this.domNodes[0],\"tc-dragover\");\n};\n\nDroppableWidget.prototype.leaveDrag = function(event) {\n\tvar pos = this.currentlyEntered.indexOf(event.target);\n\tif(pos !== -1) {\n\t\tthis.currentlyEntered.splice(pos,1);\n\t}\n\t// Remove highlighting if we're leaving externally. The hacky second condition is to resolve a problem with Firefox whereby there is an erroneous dragenter event if the node being dragged is within the dropzone\n\tif(this.currentlyEntered.length === 0 || (this.currentlyEntered.length === 1 && this.currentlyEntered[0] === $tw.dragInProgress)) {\n\t\tthis.currentlyEntered = [];\n\t\t$tw.utils.removeClass(this.domNodes[0],\"tc-dragover\");\n\t}\n};\n\nDroppableWidget.prototype.handleDragEnterEvent = function(event) {\n\tthis.enterDrag(event);\n\t// Tell the browser that we're ready to handle the drop\n\tevent.preventDefault();\n\t// Tell the browser not to ripple the drag up to any parent drop handlers\n\tevent.stopPropagation();\n\treturn false;\n};\n\nDroppableWidget.prototype.handleDragOverEvent = function(event) {\n\t// Check for being over a TEXTAREA or INPUT\n\tif([\"TEXTAREA\",\"INPUT\"].indexOf(event.target.tagName) !== -1) {\n\t\treturn false;\n\t}\n\t// Tell the browser that we're still interested in the drop\n\tevent.preventDefault();\n\t// Set the drop effect\n\tevent.dataTransfer.dropEffect = this.droppableEffect;\n\treturn false;\n};\n\nDroppableWidget.prototype.handleDragLeaveEvent = function(event) {\n\tthis.leaveDrag(event);\n\treturn false;\n};\n\nDroppableWidget.prototype.handleDropEvent = function(event) {\n\tvar self = this;\n\tthis.leaveDrag(event);\n\t// Check for being over a TEXTAREA or INPUT\n\tif([\"TEXTAREA\",\"INPUT\"].indexOf(event.target.tagName) !== -1) {\n\t\treturn false;\n\t}\n\tvar dataTransfer = event.dataTransfer;\n\t// Remove highlighting\n\t$tw.utils.removeClass(this.domNodes[0],\"tc-dragover\");\n\t// Try to import the various data types we understand\n\t$tw.utils.importDataTransfer(dataTransfer,null,function(fieldsArray) {\n\t\tfieldsArray.forEach(function(fields) {\n\t\t\tself.performActions(fields.title || fields.text,event);\n\t\t});\n\t});\n\t// Tell the browser that we handled the drop\n\tevent.preventDefault();\n\t// Stop the drop ripple up to any parent handlers\n\tevent.stopPropagation();\n\treturn false;\n};\n\nDroppableWidget.prototype.performActions = function(title,event) {\n\tif(this.droppableActions) {\n\t\tvar modifierKey = event.ctrlKey && ! event.shiftKey ? \"ctrl\" : event.shiftKey && !event.ctrlKey ? \"shift\" : \n\t\t\t\tevent.ctrlKey && event.shiftKey ? \"ctrl-shift\" : \"normal\" ;\n\t\tthis.invokeActionString(this.droppableActions,this,event,{actionTiddler: title, modifier: modifierKey});\n\t}\n};\n\n/*\nCompute the internal state of the widget\n*/\nDroppableWidget.prototype.execute = function() {\n\tthis.droppableActions = this.getAttribute(\"actions\");\n\tthis.droppableEffect = this.getAttribute(\"effect\",\"copy\");\n\tthis.droppableTag = this.getAttribute(\"tag\");\n\tthis.droppableClass = this.getAttribute(\"class\");\n\t// Make child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nDroppableWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes[\"class\"] || changedAttributes.tag) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\nexports.droppable = DroppableWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/dropzone.js": {
"title": "$:/core/modules/widgets/dropzone.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/dropzone.js\ntype: application/javascript\nmodule-type: widget\n\nDropzone widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar DropZoneWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nDropZoneWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nDropZoneWidget.prototype.render = function(parent,nextSibling) {\n\tvar self = this;\n\t// Remember parent\n\tthis.parentDomNode = parent;\n\t// Compute attributes and execute state\n\tthis.computeAttributes();\n\tthis.execute();\n\t// Create element\n\tvar domNode = this.document.createElement(\"div\");\n\tdomNode.className = \"tc-dropzone\";\n\t// Add event handlers\n\t$tw.utils.addEventListeners(domNode,[\n\t\t{name: \"dragenter\", handlerObject: this, handlerMethod: \"handleDragEnterEvent\"},\n\t\t{name: \"dragover\", handlerObject: this, handlerMethod: \"handleDragOverEvent\"},\n\t\t{name: \"dragleave\", handlerObject: this, handlerMethod: \"handleDragLeaveEvent\"},\n\t\t{name: \"drop\", handlerObject: this, handlerMethod: \"handleDropEvent\"},\n\t\t{name: \"paste\", handlerObject: this, handlerMethod: \"handlePasteEvent\"}\n\t]);\n\tdomNode.addEventListener(\"click\",function (event) {\n\t},false);\n\t// Insert element\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.renderChildren(domNode,null);\n\tthis.domNodes.push(domNode);\n\t// Stack of outstanding enter/leave events\n\tthis.currentlyEntered = [];\n};\n\nDropZoneWidget.prototype.enterDrag = function(event) {\n\tif(this.currentlyEntered.indexOf(event.target) === -1) {\n\t\tthis.currentlyEntered.push(event.target);\n\t}\n\t// If we're entering for the first time we need to apply highlighting\n\t$tw.utils.addClass(this.domNodes[0],\"tc-dragover\");\n};\n\nDropZoneWidget.prototype.leaveDrag = function(event) {\n\tvar pos = this.currentlyEntered.indexOf(event.target);\n\tif(pos !== -1) {\n\t\tthis.currentlyEntered.splice(pos,1);\n\t}\n\t// Remove highlighting if we're leaving externally\n\tif(this.currentlyEntered.length === 0) {\n\t\t$tw.utils.removeClass(this.domNodes[0],\"tc-dragover\");\n\t}\n};\n\nDropZoneWidget.prototype.handleDragEnterEvent = function(event) {\n\t// Check for this window being the source of the drag\n\tif($tw.dragInProgress) {\n\t\treturn false;\n\t}\n\tthis.enterDrag(event);\n\t// Tell the browser that we're ready to handle the drop\n\tevent.preventDefault();\n\t// Tell the browser not to ripple the drag up to any parent drop handlers\n\tevent.stopPropagation();\n};\n\nDropZoneWidget.prototype.handleDragOverEvent = function(event) {\n\t// Check for being over a TEXTAREA or INPUT\n\tif([\"TEXTAREA\",\"INPUT\"].indexOf(event.target.tagName) !== -1) {\n\t\treturn false;\n\t}\n\t// Check for this window being the source of the drag\n\tif($tw.dragInProgress) {\n\t\treturn false;\n\t}\n\t// Tell the browser that we're still interested in the drop\n\tevent.preventDefault();\n\tevent.dataTransfer.dropEffect = \"copy\"; // Explicitly show this is a copy\n};\n\nDropZoneWidget.prototype.handleDragLeaveEvent = function(event) {\n\tthis.leaveDrag(event);\n};\n\nDropZoneWidget.prototype.handleDropEvent = function(event) {\n\tvar self = this,\n\t\treadFileCallback = function(tiddlerFieldsArray) {\n\t\t\tself.dispatchEvent({type: \"tm-import-tiddlers\", param: JSON.stringify(tiddlerFieldsArray)});\n\t\t};\n\tthis.leaveDrag(event);\n\t// Check for being over a TEXTAREA or INPUT\n\tif([\"TEXTAREA\",\"INPUT\"].indexOf(event.target.tagName) !== -1) {\n\t\treturn false;\n\t}\n\t// Check for this window being the source of the drag\n\tif($tw.dragInProgress) {\n\t\treturn false;\n\t}\n\tvar self = this,\n\t\tdataTransfer = event.dataTransfer;\n\t// Remove highlighting\n\t$tw.utils.removeClass(this.domNodes[0],\"tc-dragover\");\n\t// Import any files in the drop\n\tvar numFiles = 0;\n\tif(dataTransfer.files) {\n\t\tnumFiles = this.wiki.readFiles(dataTransfer.files,{\n\t\t\tcallback: readFileCallback,\n\t\t\tdeserializer: this.dropzoneDeserializer\n\t\t});\n\t}\n\t// Try to import the various data types we understand\n\tif(numFiles === 0) {\n\t\t$tw.utils.importDataTransfer(dataTransfer,this.wiki.generateNewTitle(\"Untitled\"),readFileCallback);\n\t}\n\t// Tell the browser that we handled the drop\n\tevent.preventDefault();\n\t// Stop the drop ripple up to any parent handlers\n\tevent.stopPropagation();\n};\n\nDropZoneWidget.prototype.handlePasteEvent = function(event) {\n\tvar self = this,\n\t\treadFileCallback = function(tiddlerFieldsArray) {\n\t\t\tself.dispatchEvent({type: \"tm-import-tiddlers\", param: JSON.stringify(tiddlerFieldsArray)});\n\t\t};\n\t// Let the browser handle it if we're in a textarea or input box\n\tif([\"TEXTAREA\",\"INPUT\"].indexOf(event.target.tagName) == -1 && !event.target.isContentEditable) {\n\t\tvar self = this,\n\t\t\titems = event.clipboardData.items;\n\t\t// Enumerate the clipboard items\n\t\tfor(var t = 0; t<items.length; t++) {\n\t\t\tvar item = items[t];\n\t\t\tif(item.kind === \"file\") {\n\t\t\t\t// Import any files\n\t\t\t\tthis.wiki.readFile(item.getAsFile(),{\n\t\t\t\t\tcallback: readFileCallback,\n\t\t\t\t\tdeserializer: this.dropzoneDeserializer\n\t\t\t\t});\n\t\t\t} else if(item.kind === \"string\") {\n\t\t\t\t// Create tiddlers from string items\n\t\t\t\tvar type = item.type;\n\t\t\t\titem.getAsString(function(str) {\n\t\t\t\t\tvar tiddlerFields = {\n\t\t\t\t\t\ttitle: self.wiki.generateNewTitle(\"Untitled\"),\n\t\t\t\t\t\ttext: str,\n\t\t\t\t\t\ttype: type\n\t\t\t\t\t};\n\t\t\t\t\tif($tw.log.IMPORT) {\n\t\t\t\t\t\tconsole.log(\"Importing string '\" + str + \"', type: '\" + type + \"'\");\n\t\t\t\t\t}\n\t\t\t\t\tself.dispatchEvent({type: \"tm-import-tiddlers\", param: JSON.stringify([tiddlerFields])});\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\t// Tell the browser that we've handled the paste\n\t\tevent.stopPropagation();\n\t\tevent.preventDefault();\n\t}\n};\n\n/*\nCompute the internal state of the widget\n*/\nDropZoneWidget.prototype.execute = function() {\n\tthis.dropzoneDeserializer = this.getAttribute(\"deserializer\");\n\t// Make child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nDropZoneWidget.prototype.refresh = function(changedTiddlers) {\n\treturn this.refreshChildren(changedTiddlers);\n};\n\nexports.dropzone = DropZoneWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/edit-binary.js": {
"title": "$:/core/modules/widgets/edit-binary.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/edit-binary.js\ntype: application/javascript\nmodule-type: widget\n\nEdit-binary widget; placeholder for editing binary tiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar BINARY_WARNING_MESSAGE = \"$:/core/ui/BinaryWarning\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar EditBinaryWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nEditBinaryWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nEditBinaryWidget.prototype.render = function(parent,nextSibling) {\n\tvar self = this;\n\t// Save the parent dom node\n\tthis.parentDomNode = parent;\n\t// Compute our attributes\n\tthis.computeAttributes();\n\t// Execute our logic\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nEditBinaryWidget.prototype.execute = function() {\n\t// Construct the child widgets\n\tthis.makeChildWidgets([{\n\t\ttype: \"transclude\",\n\t\tattributes: {\n\t\t\ttiddler: {type: \"string\", value: BINARY_WARNING_MESSAGE}\n\t\t}\n\t}]);\n};\n\n/*\nRefresh by refreshing our child widget\n*/\nEditBinaryWidget.prototype.refresh = function(changedTiddlers) {\n\treturn this.refreshChildren(changedTiddlers);\n};\n\nexports[\"edit-binary\"] = EditBinaryWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/edit-bitmap.js": {
"title": "$:/core/modules/widgets/edit-bitmap.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/edit-bitmap.js\ntype: application/javascript\nmodule-type: widget\n\nEdit-bitmap widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Default image sizes\nvar DEFAULT_IMAGE_WIDTH = 600,\n\tDEFAULT_IMAGE_HEIGHT = 370;\n\n// Configuration tiddlers\nvar LINE_WIDTH_TITLE = \"$:/config/BitmapEditor/LineWidth\",\n\tLINE_COLOUR_TITLE = \"$:/config/BitmapEditor/Colour\",\n\tLINE_OPACITY_TITLE = \"$:/config/BitmapEditor/Opacity\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar EditBitmapWidget = function(parseTreeNode,options) {\n\t// Initialise the editor operations if they've not been done already\n\tif(!this.editorOperations) {\n\t\tEditBitmapWidget.prototype.editorOperations = {};\n\t\t$tw.modules.applyMethods(\"bitmapeditoroperation\",this.editorOperations);\n\t}\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nEditBitmapWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nEditBitmapWidget.prototype.render = function(parent,nextSibling) {\n\tvar self = this;\n\t// Save the parent dom node\n\tthis.parentDomNode = parent;\n\t// Compute our attributes\n\tthis.computeAttributes();\n\t// Execute our logic\n\tthis.execute();\n\t// Create the wrapper for the toolbar and render its content\n\tthis.toolbarNode = this.document.createElement(\"div\");\n\tthis.toolbarNode.className = \"tc-editor-toolbar\";\n\tparent.insertBefore(this.toolbarNode,nextSibling);\n\tthis.domNodes.push(this.toolbarNode);\n\t// Create the on-screen canvas\n\tthis.canvasDomNode = $tw.utils.domMaker(\"canvas\",{\n\t\tdocument: this.document,\n\t\t\"class\":\"tc-edit-bitmapeditor\",\n\t\teventListeners: [{\n\t\t\tname: \"touchstart\", handlerObject: this, handlerMethod: \"handleTouchStartEvent\"\n\t\t},{\n\t\t\tname: \"touchmove\", handlerObject: this, handlerMethod: \"handleTouchMoveEvent\"\n\t\t},{\n\t\t\tname: \"touchend\", handlerObject: this, handlerMethod: \"handleTouchEndEvent\"\n\t\t},{\n\t\t\tname: \"mousedown\", handlerObject: this, handlerMethod: \"handleMouseDownEvent\"\n\t\t},{\n\t\t\tname: \"mousemove\", handlerObject: this, handlerMethod: \"handleMouseMoveEvent\"\n\t\t},{\n\t\t\tname: \"mouseup\", handlerObject: this, handlerMethod: \"handleMouseUpEvent\"\n\t\t}]\n\t});\n\t// Set the width and height variables\n\tthis.setVariable(\"tv-bitmap-editor-width\",this.canvasDomNode.width + \"px\");\n\tthis.setVariable(\"tv-bitmap-editor-height\",this.canvasDomNode.height + \"px\");\n\t// Render toolbar child widgets\n\tthis.renderChildren(this.toolbarNode,null);\n\t// // Insert the elements into the DOM\n\tparent.insertBefore(this.canvasDomNode,nextSibling);\n\tthis.domNodes.push(this.canvasDomNode);\n\t// Load the image into the canvas\n\tif($tw.browser) {\n\t\tthis.loadCanvas();\n\t}\n\t// Add widget message listeners\n\tthis.addEventListeners([\n\t\t{type: \"tm-edit-bitmap-operation\", handler: \"handleEditBitmapOperationMessage\"}\n\t]);\n};\n\n/*\nHandle an edit bitmap operation message from the toolbar\n*/\nEditBitmapWidget.prototype.handleEditBitmapOperationMessage = function(event) {\n\t// Invoke the handler\n\tvar handler = this.editorOperations[event.param];\n\tif(handler) {\n\t\thandler.call(this,event);\n\t}\n};\n\n/*\nCompute the internal state of the widget\n*/\nEditBitmapWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.editTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\t// Make the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nJust refresh the toolbar\n*/\nEditBitmapWidget.prototype.refresh = function(changedTiddlers) {\n\treturn this.refreshChildren(changedTiddlers);\n};\n\n/*\nSet the bitmap size variables and refresh the toolbar\n*/\nEditBitmapWidget.prototype.refreshToolbar = function() {\n\t// Set the width and height variables\n\tthis.setVariable(\"tv-bitmap-editor-width\",this.canvasDomNode.width + \"px\");\n\tthis.setVariable(\"tv-bitmap-editor-height\",this.canvasDomNode.height + \"px\");\n\t// Refresh each of our child widgets\n\t$tw.utils.each(this.children,function(childWidget) {\n\t\tchildWidget.refreshSelf();\n\t});\n};\n\nEditBitmapWidget.prototype.loadCanvas = function() {\n\tvar tiddler = this.wiki.getTiddler(this.editTitle),\n\t\tcurrImage = new Image();\n\t// Set up event handlers for loading the image\n\tvar self = this;\n\tcurrImage.onload = function() {\n\t\t// Copy the image to the on-screen canvas\n\t\tself.initCanvas(self.canvasDomNode,currImage.width,currImage.height,currImage);\n\t\t// And also copy the current bitmap to the off-screen canvas\n\t\tself.currCanvas = self.document.createElement(\"canvas\");\n\t\tself.initCanvas(self.currCanvas,currImage.width,currImage.height,currImage);\n\t\t// Set the width and height input boxes\n\t\tself.refreshToolbar();\n\t};\n\tcurrImage.onerror = function() {\n\t\t// Set the on-screen canvas size and clear it\n\t\tself.initCanvas(self.canvasDomNode,DEFAULT_IMAGE_WIDTH,DEFAULT_IMAGE_HEIGHT);\n\t\t// Set the off-screen canvas size and clear it\n\t\tself.currCanvas = self.document.createElement(\"canvas\");\n\t\tself.initCanvas(self.currCanvas,DEFAULT_IMAGE_WIDTH,DEFAULT_IMAGE_HEIGHT);\n\t\t// Set the width and height input boxes\n\t\tself.refreshToolbar();\n\t};\n\t// Get the current bitmap into an image object\n\tcurrImage.src = \"data:\" + tiddler.fields.type + \";base64,\" + tiddler.fields.text;\n};\n\nEditBitmapWidget.prototype.initCanvas = function(canvas,width,height,image) {\n\tcanvas.width = width;\n\tcanvas.height = height;\n\tvar ctx = canvas.getContext(\"2d\");\n\tif(image) {\n\t\tctx.drawImage(image,0,0);\n\t} else {\n\t\tctx.fillStyle = \"#fff\";\n\t\tctx.fillRect(0,0,canvas.width,canvas.height);\n\t}\n};\n\n/*\n** Change the size of the canvas, preserving the current image\n*/\nEditBitmapWidget.prototype.changeCanvasSize = function(newWidth,newHeight) {\n\t// Create and size a new canvas\n\tvar newCanvas = this.document.createElement(\"canvas\");\n\tthis.initCanvas(newCanvas,newWidth,newHeight);\n\t// Copy the old image\n\tvar ctx = newCanvas.getContext(\"2d\");\n\tctx.drawImage(this.currCanvas,0,0);\n\t// Set the new canvas as the current one\n\tthis.currCanvas = newCanvas;\n\t// Set the size of the onscreen canvas\n\tthis.canvasDomNode.width = newWidth;\n\tthis.canvasDomNode.height = newHeight;\n\t// Paint the onscreen canvas with the offscreen canvas\n\tctx = this.canvasDomNode.getContext(\"2d\");\n\tctx.drawImage(this.currCanvas,0,0);\n};\n\n/*\n** Rotate the canvas left by 90 degrees\n*/\nEditBitmapWidget.prototype.rotateCanvasLeft = function() {\n\t// Get the current size of the image\n\tvar origWidth = this.currCanvas.width,\n\t\torigHeight = this.currCanvas.height;\n\t// Create and size a new canvas\n\tvar newCanvas = this.document.createElement(\"canvas\"),\n\t\tnewWidth = origHeight,\n\t\tnewHeight = origWidth;\n\tthis.initCanvas(newCanvas,newWidth,newHeight);\n\t// Copy the old image\n\tvar ctx = newCanvas.getContext(\"2d\");\n\tctx.save();\n\tctx.translate(newWidth / 2,newHeight / 2);\n\tctx.rotate(-Math.PI / 2);\n\tctx.drawImage(this.currCanvas,-origWidth / 2,-origHeight / 2);\n\tctx.restore();\n\t// Set the new canvas as the current one\n\tthis.currCanvas = newCanvas;\n\t// Set the size of the onscreen canvas\n\tthis.canvasDomNode.width = newWidth;\n\tthis.canvasDomNode.height = newHeight;\n\t// Paint the onscreen canvas with the offscreen canvas\n\tctx = this.canvasDomNode.getContext(\"2d\");\n\tctx.drawImage(this.currCanvas,0,0);\n};\n\nEditBitmapWidget.prototype.handleTouchStartEvent = function(event) {\n\tthis.brushDown = true;\n\tthis.strokeStart(event.touches[0].clientX,event.touches[0].clientY);\n\tevent.preventDefault();\n\tevent.stopPropagation();\n\treturn false;\n};\n\nEditBitmapWidget.prototype.handleTouchMoveEvent = function(event) {\n\tif(this.brushDown) {\n\t\tthis.strokeMove(event.touches[0].clientX,event.touches[0].clientY);\n\t}\n\tevent.preventDefault();\n\tevent.stopPropagation();\n\treturn false;\n};\n\nEditBitmapWidget.prototype.handleTouchEndEvent = function(event) {\n\tif(this.brushDown) {\n\t\tthis.brushDown = false;\n\t\tthis.strokeEnd();\n\t}\n\tevent.preventDefault();\n\tevent.stopPropagation();\n\treturn false;\n};\n\nEditBitmapWidget.prototype.handleMouseDownEvent = function(event) {\n\tthis.strokeStart(event.clientX,event.clientY);\n\tthis.brushDown = true;\n\tevent.preventDefault();\n\tevent.stopPropagation();\n\treturn false;\n};\n\nEditBitmapWidget.prototype.handleMouseMoveEvent = function(event) {\n\tif(this.brushDown) {\n\t\tthis.strokeMove(event.clientX,event.clientY);\n\t\tevent.preventDefault();\n\t\tevent.stopPropagation();\n\t\treturn false;\n\t}\n\treturn true;\n};\n\nEditBitmapWidget.prototype.handleMouseUpEvent = function(event) {\n\tif(this.brushDown) {\n\t\tthis.brushDown = false;\n\t\tthis.strokeEnd();\n\t\tevent.preventDefault();\n\t\tevent.stopPropagation();\n\t\treturn false;\n\t}\n\treturn true;\n};\n\nEditBitmapWidget.prototype.adjustCoordinates = function(x,y) {\n\tvar canvasRect = this.canvasDomNode.getBoundingClientRect(),\n\t\tscale = this.canvasDomNode.width/canvasRect.width;\n\treturn {x: (x - canvasRect.left) * scale, y: (y - canvasRect.top) * scale};\n};\n\nEditBitmapWidget.prototype.strokeStart = function(x,y) {\n\t// Start off a new stroke\n\tthis.stroke = [this.adjustCoordinates(x,y)];\n};\n\nEditBitmapWidget.prototype.strokeMove = function(x,y) {\n\tvar ctx = this.canvasDomNode.getContext(\"2d\"),\n\t\tt;\n\t// Add the new position to the end of the stroke\n\tthis.stroke.push(this.adjustCoordinates(x,y));\n\t// Redraw the previous image\n\tctx.drawImage(this.currCanvas,0,0);\n\t// Render the stroke\n\tctx.globalAlpha = parseFloat(this.wiki.getTiddlerText(LINE_OPACITY_TITLE,\"1.0\"));\n\tctx.strokeStyle = this.wiki.getTiddlerText(LINE_COLOUR_TITLE,\"#ff0\");\n\tctx.lineWidth = parseFloat(this.wiki.getTiddlerText(LINE_WIDTH_TITLE,\"3\"));\n\tctx.lineCap = \"round\";\n\tctx.lineJoin = \"round\";\n\tctx.beginPath();\n\tctx.moveTo(this.stroke[0].x,this.stroke[0].y);\n\tfor(t=1; t<this.stroke.length-1; t++) {\n\t\tvar s1 = this.stroke[t],\n\t\t\ts2 = this.stroke[t-1],\n\t\t\ttx = (s1.x + s2.x)/2,\n\t\t\tty = (s1.y + s2.y)/2;\n\t\tctx.quadraticCurveTo(s2.x,s2.y,tx,ty);\n\t}\n\tctx.stroke();\n};\n\nEditBitmapWidget.prototype.strokeEnd = function() {\n\t// Copy the bitmap to the off-screen canvas\n\tvar ctx = this.currCanvas.getContext(\"2d\");\n\tctx.drawImage(this.canvasDomNode,0,0);\n\t// Save the image into the tiddler\n\tthis.saveChanges();\n};\n\nEditBitmapWidget.prototype.saveChanges = function() {\n\tvar tiddler = this.wiki.getTiddler(this.editTitle);\n\tif(tiddler) {\n\t\t// data URIs look like \"data:<type>;base64,<text>\"\n\t\tvar dataURL = this.canvasDomNode.toDataURL(tiddler.fields.type),\n\t\t\tposColon = dataURL.indexOf(\":\"),\n\t\t\tposSemiColon = dataURL.indexOf(\";\"),\n\t\t\tposComma = dataURL.indexOf(\",\"),\n\t\t\ttype = dataURL.substring(posColon+1,posSemiColon),\n\t\t\ttext = dataURL.substring(posComma+1);\n\t\tvar update = {type: type, text: text};\n\t\tthis.wiki.addTiddler(new $tw.Tiddler(this.wiki.getModificationFields(),tiddler,update,this.wiki.getCreationFields()));\n\t}\n};\n\nexports[\"edit-bitmap\"] = EditBitmapWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/edit-shortcut.js": {
"title": "$:/core/modules/widgets/edit-shortcut.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/edit-shortcut.js\ntype: application/javascript\nmodule-type: widget\n\nWidget to display an editable keyboard shortcut\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar EditShortcutWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nEditShortcutWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nEditShortcutWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.inputNode = this.document.createElement(\"input\");\n\t// Assign classes\n\tif(this.shortcutClass) {\n\t\tthis.inputNode.className = this.shortcutClass;\t\t\n\t}\n\t// Assign other attributes\n\tif(this.shortcutStyle) {\n\t\tthis.inputNode.setAttribute(\"style\",this.shortcutStyle);\n\t}\n\tif(this.shortcutTooltip) {\n\t\tthis.inputNode.setAttribute(\"title\",this.shortcutTooltip);\n\t}\n\tif(this.shortcutPlaceholder) {\n\t\tthis.inputNode.setAttribute(\"placeholder\",this.shortcutPlaceholder);\n\t}\n\tif(this.shortcutAriaLabel) {\n\t\tthis.inputNode.setAttribute(\"aria-label\",this.shortcutAriaLabel);\n\t}\n\t// Assign the current shortcut\n\tthis.updateInputNode();\n\t// Add event handlers\n\t$tw.utils.addEventListeners(this.inputNode,[\n\t\t{name: \"keydown\", handlerObject: this, handlerMethod: \"handleKeydownEvent\"}\n\t]);\n\t// Link into the DOM\n\tparent.insertBefore(this.inputNode,nextSibling);\n\tthis.domNodes.push(this.inputNode);\n};\n\n/*\nCompute the internal state of the widget\n*/\nEditShortcutWidget.prototype.execute = function() {\n\tthis.shortcutTiddler = this.getAttribute(\"tiddler\");\n\tthis.shortcutField = this.getAttribute(\"field\");\n\tthis.shortcutIndex = this.getAttribute(\"index\");\n\tthis.shortcutPlaceholder = this.getAttribute(\"placeholder\");\n\tthis.shortcutDefault = this.getAttribute(\"default\",\"\");\n\tthis.shortcutClass = this.getAttribute(\"class\");\n\tthis.shortcutStyle = this.getAttribute(\"style\");\n\tthis.shortcutTooltip = this.getAttribute(\"tooltip\");\n\tthis.shortcutAriaLabel = this.getAttribute(\"aria-label\");\n};\n\n/*\nUpdate the value of the input node\n*/\nEditShortcutWidget.prototype.updateInputNode = function() {\n\tif(this.shortcutField) {\n\t\tvar tiddler = this.wiki.getTiddler(this.shortcutTiddler);\n\t\tif(tiddler && $tw.utils.hop(tiddler.fields,this.shortcutField)) {\n\t\t\tthis.inputNode.value = tiddler.getFieldString(this.shortcutField);\n\t\t} else {\n\t\t\tthis.inputNode.value = this.shortcutDefault;\n\t\t}\n\t} else if(this.shortcutIndex) {\n\t\tthis.inputNode.value = this.wiki.extractTiddlerDataItem(this.shortcutTiddler,this.shortcutIndex,this.shortcutDefault);\n\t} else {\n\t\tthis.inputNode.value = this.wiki.getTiddlerText(this.shortcutTiddler,this.shortcutDefault);\n\t}\n};\n\n/*\nHandle a dom \"keydown\" event\n*/\nEditShortcutWidget.prototype.handleKeydownEvent = function(event) {\n\t// Ignore shift, ctrl, meta, alt\n\tif(event.keyCode && $tw.keyboardManager.getModifierKeys().indexOf(event.keyCode) === -1) {\n\t\t// Get the shortcut text representation\n\t\tvar value = $tw.keyboardManager.getPrintableShortcuts([{\n\t\t\tctrlKey: event.ctrlKey,\n\t\t\tshiftKey: event.shiftKey,\n\t\t\taltKey: event.altKey,\n\t\t\tmetaKey: event.metaKey,\n\t\t\tkeyCode: event.keyCode\n\t\t}]);\n\t\tif(value.length > 0) {\n\t\t\tthis.wiki.setText(this.shortcutTiddler,this.shortcutField,this.shortcutIndex,value[0]);\n\t\t}\n\t\t// Ignore the keydown if it was already handled\n\t\tevent.preventDefault();\n\t\tevent.stopPropagation();\n\t\treturn true;\t\t\n\t} else {\n\t\treturn false;\n\t}\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget needed re-rendering\n*/\nEditShortcutWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes.placeholder || changedAttributes[\"default\"] || changedAttributes[\"class\"] || changedAttributes.style || changedAttributes.tooltip || changedAttributes[\"aria-label\"]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else if(changedTiddlers[this.shortcutTiddler]) {\n\t\tthis.updateInputNode();\n\t\treturn true;\n\t} else {\n\t\treturn false;\t\n\t}\n};\n\nexports[\"edit-shortcut\"] = EditShortcutWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/edit-text.js": {
"title": "$:/core/modules/widgets/edit-text.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/edit-text.js\ntype: application/javascript\nmodule-type: widget\n\nEdit-text widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar editTextWidgetFactory = require(\"$:/core/modules/editor/factory.js\").editTextWidgetFactory,\n\tFramedEngine = require(\"$:/core/modules/editor/engines/framed.js\").FramedEngine,\n\tSimpleEngine = require(\"$:/core/modules/editor/engines/simple.js\").SimpleEngine;\n\nexports[\"edit-text\"] = editTextWidgetFactory(FramedEngine,SimpleEngine);\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/edit.js": {
"title": "$:/core/modules/widgets/edit.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/edit.js\ntype: application/javascript\nmodule-type: widget\n\nEdit widget is a meta-widget chooses the appropriate actual editting widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar EditWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nEditWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nEditWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n// Mappings from content type to editor type are stored in tiddlers with this prefix\nvar EDITOR_MAPPING_PREFIX = \"$:/config/EditorTypeMappings/\";\n\n/*\nCompute the internal state of the widget\n*/\nEditWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.editTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\tthis.editField = this.getAttribute(\"field\",\"text\");\n\tthis.editIndex = this.getAttribute(\"index\");\n\tthis.editClass = this.getAttribute(\"class\");\n\tthis.editPlaceholder = this.getAttribute(\"placeholder\");\n\t// Choose the appropriate edit widget\n\tthis.editorType = this.getEditorType();\n\t// Make the child widgets\n\tthis.makeChildWidgets([{\n\t\ttype: \"edit-\" + this.editorType,\n\t\tattributes: {\n\t\t\ttiddler: {type: \"string\", value: this.editTitle},\n\t\t\tfield: {type: \"string\", value: this.editField},\n\t\t\tindex: {type: \"string\", value: this.editIndex},\n\t\t\t\"class\": {type: \"string\", value: this.editClass},\n\t\t\t\"placeholder\": {type: \"string\", value: this.editPlaceholder}\n\t\t},\n\t\tchildren: this.parseTreeNode.children\n\t}]);\n};\n\nEditWidget.prototype.getEditorType = function() {\n\t// Get the content type of the thing we're editing\n\tvar type;\n\tif(this.editField === \"text\") {\n\t\tvar tiddler = this.wiki.getTiddler(this.editTitle);\n\t\tif(tiddler) {\n\t\t\ttype = tiddler.fields.type;\n\t\t}\n\t}\n\ttype = type || \"text/vnd.tiddlywiki\";\n\tvar editorType = this.wiki.getTiddlerText(EDITOR_MAPPING_PREFIX + type);\n\tif(!editorType) {\n\t\tvar typeInfo = $tw.config.contentTypeInfo[type];\n\t\tif(typeInfo && typeInfo.encoding === \"base64\") {\n\t\t\teditorType = \"binary\";\n\t\t} else {\n\t\t\teditorType = \"text\";\n\t\t}\n\t}\n\treturn editorType;\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nEditWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\t// Refresh if an attribute has changed, or the type associated with the target tiddler has changed\n\tif(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || (changedTiddlers[this.editTitle] && this.getEditorType() !== this.editorType)) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\t\t\n\t}\n};\n\nexports.edit = EditWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/element.js": {
"title": "$:/core/modules/widgets/element.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/element.js\ntype: application/javascript\nmodule-type: widget\n\nElement widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar ElementWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nElementWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nElementWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\t// Neuter blacklisted elements\n\tvar tag = this.parseTreeNode.tag;\n\tif($tw.config.htmlUnsafeElements.indexOf(tag) !== -1) {\n\t\ttag = \"safe-\" + tag;\n\t}\n\t// Adjust headings by the current base level\n\tvar headingLevel = [\"h1\",\"h2\",\"h3\",\"h4\",\"h5\",\"h6\"].indexOf(tag);\n\tif(headingLevel !== -1) {\n\t\tvar baseLevel = parseInt(this.getVariable(\"tv-adjust-heading-level\",\"0\"),10) || 0;\n\t\theadingLevel = Math.min(Math.max(headingLevel + 1 + baseLevel,1),6);\n\t\ttag = \"h\" + headingLevel;\n\t}\n\t// Create the DOM node\n\tvar domNode = this.document.createElementNS(this.namespace,tag);\n\tthis.assignAttributes(domNode,{excludeEventAttributes: true});\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.renderChildren(domNode,null);\n\tthis.domNodes.push(domNode);\n};\n\n/*\nCompute the internal state of the widget\n*/\nElementWidget.prototype.execute = function() {\n\t// Select the namespace for the tag\n\tvar tagNamespaces = {\n\t\t\tsvg: \"http://www.w3.org/2000/svg\",\n\t\t\tmath: \"http://www.w3.org/1998/Math/MathML\",\n\t\t\tbody: \"http://www.w3.org/1999/xhtml\"\n\t\t};\n\tthis.namespace = tagNamespaces[this.parseTreeNode.tag];\n\tif(this.namespace) {\n\t\tthis.setVariable(\"namespace\",this.namespace);\n\t} else {\n\t\tthis.namespace = this.getVariable(\"namespace\",{defaultValue: \"http://www.w3.org/1999/xhtml\"});\n\t}\n\t// Make the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nElementWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes(),\n\t\thasChangedAttributes = $tw.utils.count(changedAttributes) > 0;\n\tif(hasChangedAttributes) {\n\t\t// Update our attributes\n\t\tthis.assignAttributes(this.domNodes[0],{excludeEventAttributes: true});\n\t}\n\treturn this.refreshChildren(changedTiddlers) || hasChangedAttributes;\n};\n\nexports.element = ElementWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/encrypt.js": {
"title": "$:/core/modules/widgets/encrypt.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/encrypt.js\ntype: application/javascript\nmodule-type: widget\n\nEncrypt widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar EncryptWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nEncryptWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nEncryptWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tvar textNode = this.document.createTextNode(this.encryptedText);\n\tparent.insertBefore(textNode,nextSibling);\n\tthis.domNodes.push(textNode);\n};\n\n/*\nCompute the internal state of the widget\n*/\nEncryptWidget.prototype.execute = function() {\n\t// Get parameters from our attributes\n\tthis.filter = this.getAttribute(\"filter\",\"[!is[system]]\");\n\t// Encrypt the filtered tiddlers\n\tvar tiddlers = this.wiki.filterTiddlers(this.filter),\n\t\tjson = {},\n\t\tself = this;\n\t$tw.utils.each(tiddlers,function(title) {\n\t\tvar tiddler = self.wiki.getTiddler(title),\n\t\t\tjsonTiddler = {};\n\t\tfor(var f in tiddler.fields) {\n\t\t\tjsonTiddler[f] = tiddler.getFieldString(f);\n\t\t}\n\t\tjson[title] = jsonTiddler;\n\t});\n\tthis.encryptedText = $tw.utils.htmlEncode($tw.crypto.encrypt(JSON.stringify(json)));\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nEncryptWidget.prototype.refresh = function(changedTiddlers) {\n\t// We don't need to worry about refreshing because the encrypt widget isn't for interactive use\n\treturn false;\n};\n\nexports.encrypt = EncryptWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/entity.js": {
"title": "$:/core/modules/widgets/entity.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/entity.js\ntype: application/javascript\nmodule-type: widget\n\nHTML entity widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar EntityWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nEntityWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nEntityWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.execute();\n\tvar entityString = this.getAttribute(\"entity\",this.parseTreeNode.entity || \"\"),\n\t\ttextNode = this.document.createTextNode($tw.utils.entityDecode(entityString));\n\tparent.insertBefore(textNode,nextSibling);\n\tthis.domNodes.push(textNode);\n};\n\n/*\nCompute the internal state of the widget\n*/\nEntityWidget.prototype.execute = function() {\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nEntityWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.entity) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn false;\t\n\t}\n};\n\nexports.entity = EntityWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/fieldmangler.js": {
"title": "$:/core/modules/widgets/fieldmangler.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/fieldmangler.js\ntype: application/javascript\nmodule-type: widget\n\nField mangler widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar FieldManglerWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n\tthis.addEventListeners([\n\t\t{type: \"tm-remove-field\", handler: \"handleRemoveFieldEvent\"},\n\t\t{type: \"tm-add-field\", handler: \"handleAddFieldEvent\"},\n\t\t{type: \"tm-remove-tag\", handler: \"handleRemoveTagEvent\"},\n\t\t{type: \"tm-add-tag\", handler: \"handleAddTagEvent\"}\n\t]);\n};\n\n/*\nInherit from the base widget class\n*/\nFieldManglerWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nFieldManglerWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nFieldManglerWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.mangleTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\t// Construct the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nFieldManglerWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.tiddler) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\t\t\n\t}\n};\n\nFieldManglerWidget.prototype.handleRemoveFieldEvent = function(event) {\n\tvar tiddler = this.wiki.getTiddler(this.mangleTitle),\n\t\tdeletion = {};\n\tdeletion[event.param] = undefined;\n\tthis.wiki.addTiddler(new $tw.Tiddler(tiddler,deletion));\n\treturn true;\n};\n\nFieldManglerWidget.prototype.handleAddFieldEvent = function(event) {\n\tvar tiddler = this.wiki.getTiddler(this.mangleTitle),\n\t\taddition = this.wiki.getModificationFields(),\n\t\thadInvalidFieldName = false,\n\t\taddField = function(name,value) {\n\t\t\tvar trimmedName = name.toLowerCase().trim();\n\t\t\tif(!$tw.utils.isValidFieldName(trimmedName)) {\n\t\t\t\tif(!hadInvalidFieldName) {\n\t\t\t\t\talert($tw.language.getString(\n\t\t\t\t\t\t\"InvalidFieldName\",\n\t\t\t\t\t\t{variables:\n\t\t\t\t\t\t\t{fieldName: trimmedName}\n\t\t\t\t\t\t}\n\t\t\t\t\t));\n\t\t\t\t\thadInvalidFieldName = true;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif(!value && tiddler) {\n\t\t\t\t\tvalue = tiddler.fields[trimmedName];\n\t\t\t\t}\n\t\t\t\taddition[trimmedName] = value || \"\";\n\t\t\t}\n\t\t\treturn;\n\t\t};\n\taddition.title = this.mangleTitle;\n\tif(typeof event.param === \"string\") {\n\t\taddField(event.param,\"\");\n\t}\n\tif(typeof event.paramObject === \"object\") {\n\t\tfor(var name in event.paramObject) {\n\t\t\taddField(name,event.paramObject[name]);\n\t\t}\n\t}\n\tthis.wiki.addTiddler(new $tw.Tiddler(tiddler,addition));\n\treturn true;\n};\n\nFieldManglerWidget.prototype.handleRemoveTagEvent = function(event) {\n\tvar tiddler = this.wiki.getTiddler(this.mangleTitle),\n\t\tmodification = this.wiki.getModificationFields();\n\tif(tiddler && tiddler.fields.tags) {\n\t\tvar p = tiddler.fields.tags.indexOf(event.param);\n\t\tif(p !== -1) {\n\t\t\tmodification.tags = (tiddler.fields.tags || []).slice(0);\n\t\t\tmodification.tags.splice(p,1);\n\t\t\tif(modification.tags.length === 0) {\n\t\t\t\tmodification.tags = undefined;\n\t\t\t}\n\t\t\tthis.wiki.addTiddler(new $tw.Tiddler(tiddler,modification));\n\t\t}\n\t}\n\treturn true;\n};\n\nFieldManglerWidget.prototype.handleAddTagEvent = function(event) {\n\tvar tiddler = this.wiki.getTiddler(this.mangleTitle),\n\t\tmodification = this.wiki.getModificationFields();\n\tif(tiddler && typeof event.param === \"string\") {\n\t\tvar tag = event.param.trim();\n\t\tif(tag !== \"\") {\n\t\t\tmodification.tags = (tiddler.fields.tags || []).slice(0);\n\t\t\t$tw.utils.pushTop(modification.tags,tag);\n\t\t\tthis.wiki.addTiddler(new $tw.Tiddler(tiddler,modification));\t\t\t\n\t\t}\n\t} else if(typeof event.param === \"string\" && event.param.trim() !== \"\" && this.mangleTitle.trim() !== \"\") {\n\t\tvar tag = [];\n\t\ttag.push(event.param.trim());\n\t\tthis.wiki.addTiddler(new $tw.Tiddler({title: this.mangleTitle, tags: tag},modification));\n\t}\n\treturn true;\n};\n\nexports.fieldmangler = FieldManglerWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/fields.js": {
"title": "$:/core/modules/widgets/fields.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/fields.js\ntype: application/javascript\nmodule-type: widget\n\nFields widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar FieldsWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nFieldsWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nFieldsWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tvar textNode = this.document.createTextNode(this.text);\n\tparent.insertBefore(textNode,nextSibling);\n\tthis.domNodes.push(textNode);\n};\n\n/*\nCompute the internal state of the widget\n*/\nFieldsWidget.prototype.execute = function() {\n\t// Get parameters from our attributes\n\tthis.tiddlerTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\tthis.template = this.getAttribute(\"template\");\n\tthis.exclude = this.getAttribute(\"exclude\");\n\tthis.stripTitlePrefix = this.getAttribute(\"stripTitlePrefix\",\"no\") === \"yes\";\n\t// Get the value to display\n\tvar tiddler = this.wiki.getTiddler(this.tiddlerTitle);\n\t// Get the exclusion list\n\tvar exclude;\n\tif(this.exclude) {\n\t\texclude = this.exclude.split(\" \");\n\t} else {\n\t\texclude = [\"text\"]; \n\t}\n\t// Compose the template\n\tvar text = [];\n\tif(this.template && tiddler) {\n\t\tvar fields = [];\n\t\tfor(var fieldName in tiddler.fields) {\n\t\t\tif(exclude.indexOf(fieldName) === -1) {\n\t\t\t\tfields.push(fieldName);\n\t\t\t}\n\t\t}\n\t\tfields.sort();\n\t\tfor(var f=0; f<fields.length; f++) {\n\t\t\tfieldName = fields[f];\n\t\t\tif(exclude.indexOf(fieldName) === -1) {\n\t\t\t\tvar row = this.template,\n\t\t\t\t\tvalue = tiddler.getFieldString(fieldName);\n\t\t\t\tif(this.stripTitlePrefix && fieldName === \"title\") {\n\t\t\t\t\tvar reStrip = /^\\{[^\\}]+\\}(.+)/mg,\n\t\t\t\t\t\treMatch = reStrip.exec(value);\n\t\t\t\t\tif(reMatch) {\n\t\t\t\t\t\tvalue = reMatch[1];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\trow = $tw.utils.replaceString(row,\"$name$\",fieldName);\n\t\t\t\trow = $tw.utils.replaceString(row,\"$value$\",value);\n\t\t\t\trow = $tw.utils.replaceString(row,\"$encoded_value$\",$tw.utils.htmlEncode(value));\n\t\t\t\ttext.push(row);\n\t\t\t}\n\t\t}\n\t}\n\tthis.text = text.join(\"\");\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nFieldsWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.tiddler || changedAttributes.template || changedAttributes.exclude || changedAttributes.stripTitlePrefix || changedTiddlers[this.tiddlerTitle]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn false;\t\n\t}\n};\n\nexports.fields = FieldsWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/image.js": {
"title": "$:/core/modules/widgets/image.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/image.js\ntype: application/javascript\nmodule-type: widget\n\nThe image widget displays an image referenced with an external URI or with a local tiddler title.\n\n```\n<$image src=\"TiddlerTitle\" width=\"320\" height=\"400\" class=\"classnames\">\n```\n\nThe image source can be the title of an existing tiddler or the URL of an external image.\n\nExternal images always generate an HTML `<img>` tag.\n\nTiddlers that have a _canonical_uri field generate an HTML `<img>` tag with the src attribute containing the URI.\n\nTiddlers that contain image data generate an HTML `<img>` tag with the src attribute containing a base64 representation of the image.\n\nTiddlers that contain wikitext could be rendered to a DIV of the usual size of a tiddler, and then transformed to the size requested.\n\nThe width and height attributes are interpreted as a number of pixels, and do not need to include the \"px\" suffix.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar ImageWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nImageWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nImageWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\t// Create element\n\t// Determine what type of image it is\n\tvar tag = \"img\", src = \"\",\n\t\ttiddler = this.wiki.getTiddler(this.imageSource);\n\tif(!tiddler) {\n\t\t// The source isn't the title of a tiddler, so we'll assume it's a URL\n\t\tsrc = this.getVariable(\"tv-get-export-image-link\",{params: [{name: \"src\",value: this.imageSource}],defaultValue: this.imageSource});\n\t} else {\n\t\t// Check if it is an image tiddler\n\t\tif(this.wiki.isImageTiddler(this.imageSource)) {\n\t\t\tvar type = tiddler.fields.type,\n\t\t\t\ttext = tiddler.fields.text,\n\t\t\t\t_canonical_uri = tiddler.fields._canonical_uri;\n\t\t\t// If the tiddler has body text then it doesn't need to be lazily loaded\n\t\t\tif(text) {\n\t\t\t\t// Render the appropriate element for the image type\n\t\t\t\tswitch(type) {\n\t\t\t\t\tcase \"application/pdf\":\n\t\t\t\t\t\ttag = \"embed\";\n\t\t\t\t\t\tsrc = \"data:application/pdf;base64,\" + text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"image/svg+xml\":\n\t\t\t\t\t\tsrc = \"data:image/svg+xml,\" + encodeURIComponent(text);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tsrc = \"data:\" + type + \";base64,\" + text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t} else if(_canonical_uri) {\n\t\t\t\tswitch(type) {\n\t\t\t\t\tcase \"application/pdf\":\n\t\t\t\t\t\ttag = \"embed\";\n\t\t\t\t\t\tsrc = _canonical_uri;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"image/svg+xml\":\n\t\t\t\t\t\tsrc = _canonical_uri;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tsrc = _canonical_uri;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\t\n\t\t\t} else {\n\t\t\t\t// Just trigger loading of the tiddler\n\t\t\t\tthis.wiki.getTiddlerText(this.imageSource);\n\t\t\t}\n\t\t}\n\t}\n\t// Create the element and assign the attributes\n\tvar domNode = this.document.createElement(tag);\n\tdomNode.setAttribute(\"src\",src);\n\tif(this.imageClass) {\n\t\tdomNode.setAttribute(\"class\",this.imageClass);\t\t\n\t}\n\tif(this.imageWidth) {\n\t\tdomNode.setAttribute(\"width\",this.imageWidth);\n\t}\n\tif(this.imageHeight) {\n\t\tdomNode.setAttribute(\"height\",this.imageHeight);\n\t}\n\tif(this.imageTooltip) {\n\t\tdomNode.setAttribute(\"title\",this.imageTooltip);\t\t\n\t}\n\tif(this.imageAlt) {\n\t\tdomNode.setAttribute(\"alt\",this.imageAlt);\t\t\n\t}\n\t// Insert element\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.domNodes.push(domNode);\n};\n\n/*\nCompute the internal state of the widget\n*/\nImageWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.imageSource = this.getAttribute(\"source\");\n\tthis.imageWidth = this.getAttribute(\"width\");\n\tthis.imageHeight = this.getAttribute(\"height\");\n\tthis.imageClass = this.getAttribute(\"class\");\n\tthis.imageTooltip = this.getAttribute(\"tooltip\");\n\tthis.imageAlt = this.getAttribute(\"alt\");\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nImageWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.source || changedAttributes.width || changedAttributes.height || changedAttributes[\"class\"] || changedAttributes.tooltip || changedTiddlers[this.imageSource]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn false;\t\t\n\t}\n};\n\nexports.image = ImageWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/importvariables.js": {
"title": "$:/core/modules/widgets/importvariables.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/importvariables.js\ntype: application/javascript\nmodule-type: widget\n\nImport variable definitions from other tiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar ImportVariablesWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nImportVariablesWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nImportVariablesWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nImportVariablesWidget.prototype.execute = function(tiddlerList) {\n\tvar self = this;\n\t// Get our parameters\n\tthis.filter = this.getAttribute(\"filter\");\n\t// Compute the filter\n\tthis.tiddlerList = tiddlerList || this.wiki.filterTiddlers(this.filter,this);\n\t// Accumulate the <$set> widgets from each tiddler\n\tvar widgetStackStart,widgetStackEnd;\n\tfunction addWidgetNode(widgetNode) {\n\t\tif(widgetNode) {\n\t\t\tif(!widgetStackStart && !widgetStackEnd) {\n\t\t\t\twidgetStackStart = widgetNode;\n\t\t\t\twidgetStackEnd = widgetNode;\n\t\t\t} else {\n\t\t\t\twidgetStackEnd.children = [widgetNode];\n\t\t\t\twidgetStackEnd = widgetNode;\n\t\t\t}\n\t\t}\n\t}\n\t$tw.utils.each(this.tiddlerList,function(title) {\n\t\tvar parser = self.wiki.parseTiddler(title);\n\t\tif(parser) {\n\t\t\tvar parseTreeNode = parser.tree[0];\n\t\t\twhile(parseTreeNode && parseTreeNode.type === \"set\") {\n\t\t\t\taddWidgetNode({\n\t\t\t\t\ttype: \"set\",\n\t\t\t\t\tattributes: parseTreeNode.attributes,\n\t\t\t\t\tparams: parseTreeNode.params,\n\t\t\t\t\tisMacroDefinition: parseTreeNode.isMacroDefinition\n\t\t\t\t});\n\t\t\t\tparseTreeNode = parseTreeNode.children[0];\n\t\t\t}\n\t\t} \n\t});\n\t// Add our own children to the end of the pile\n\tvar parseTreeNodes;\n\tif(widgetStackStart && widgetStackEnd) {\n\t\tparseTreeNodes = [widgetStackStart];\n\t\twidgetStackEnd.children = this.parseTreeNode.children;\n\t} else {\n\t\tparseTreeNodes = this.parseTreeNode.children;\n\t}\n\t// Construct the child widgets\n\tthis.makeChildWidgets(parseTreeNodes);\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nImportVariablesWidget.prototype.refresh = function(changedTiddlers) {\n\t// Recompute our attributes and the filter list\n\tvar changedAttributes = this.computeAttributes(),\n\t\ttiddlerList = this.wiki.filterTiddlers(this.getAttribute(\"filter\"),this);\n\t// Refresh if the filter has changed, or the list of tiddlers has changed, or any of the tiddlers in the list has changed\n\tfunction haveListedTiddlersChanged() {\n\t\tvar changed = false;\n\t\ttiddlerList.forEach(function(title) {\n\t\t\tif(changedTiddlers[title]) {\n\t\t\t\tchanged = true;\n\t\t\t}\n\t\t});\n\t\treturn changed;\n\t}\n\tif(changedAttributes.filter || !$tw.utils.isArrayEqual(this.tiddlerList,tiddlerList) || haveListedTiddlersChanged()) {\n\t\t// Compute the filter\n\t\tthis.removeChildDomNodes();\n\t\tthis.execute(tiddlerList);\n\t\tthis.renderChildren(this.parentDomNode,this.findNextSiblingDomNode());\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\t\t\n\t}\n};\n\nexports.importvariables = ImportVariablesWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/keyboard.js": {
"title": "$:/core/modules/widgets/keyboard.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/keyboard.js\ntype: application/javascript\nmodule-type: widget\n\nKeyboard shortcut widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar KeyboardWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nKeyboardWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nKeyboardWidget.prototype.render = function(parent,nextSibling) {\n\tvar self = this;\n\t// Remember parent\n\tthis.parentDomNode = parent;\n\t// Compute attributes and execute state\n\tthis.computeAttributes();\n\tthis.execute();\n\tvar tag = this.parseTreeNode.isBlock ? \"div\" : \"span\";\n\tif(this.tag && $tw.config.htmlUnsafeElements.indexOf(this.tag) === -1) {\n\t\ttag = this.tag;\n\t}\n\t// Create element\n\tvar domNode = this.document.createElement(tag);\n\t// Assign classes\n\tvar classes = (this[\"class\"] || \"\").split(\" \");\n\tclasses.push(\"tc-keyboard\");\n\tdomNode.className = classes.join(\" \");\n\t// Add a keyboard event handler\n\tdomNode.addEventListener(\"keydown\",function (event) {\n\t\tif($tw.keyboardManager.checkKeyDescriptors(event,self.keyInfoArray)) {\n\t\t\tself.invokeActions(self,event);\n\t\t\tif(self.actions) {\n\t\t\t\tself.invokeActionString(self.actions,self,event);\n\t\t\t}\n\t\t\tself.dispatchMessage(event);\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t},false);\n\t// Insert element\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.renderChildren(domNode,null);\n\tthis.domNodes.push(domNode);\n};\n\nKeyboardWidget.prototype.dispatchMessage = function(event) {\n\tthis.dispatchEvent({type: this.message, param: this.param, tiddlerTitle: this.getVariable(\"currentTiddler\")});\n};\n\n/*\nCompute the internal state of the widget\n*/\nKeyboardWidget.prototype.execute = function() {\n\tvar self = this;\n\t// Get attributes\n\tthis.actions = this.getAttribute(\"actions\");\n\tthis.message = this.getAttribute(\"message\");\n\tthis.param = this.getAttribute(\"param\");\n\tthis.key = this.getAttribute(\"key\");\n\tthis.tag = this.getAttribute(\"tag\");\n\tthis.keyInfoArray = $tw.keyboardManager.parseKeyDescriptors(this.key);\n\tthis[\"class\"] = this.getAttribute(\"class\");\n\tif(this.key.substr(0,2) === \"((\" && this.key.substr(-2,2) === \"))\") {\n\t\tthis.shortcutTiddlers = [];\n\t\tvar name = this.key.substring(2,this.key.length -2);\n\t\t$tw.utils.each($tw.keyboardManager.lookupNames,function(platformDescriptor) {\n\t\t\tself.shortcutTiddlers.push(\"$:/config/\" + platformDescriptor + \"/\" + name);\n\t\t});\n\t}\n\t// Make child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nKeyboardWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.message || changedAttributes.param || changedAttributes.key || changedAttributes[\"class\"] || changedAttributes.tag) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\t// Update the keyInfoArray if one of its shortcut-config-tiddlers has changed\n\tif(this.shortcutTiddlers && $tw.utils.hopArray(changedTiddlers,this.shortcutTiddlers)) {\n\t\tthis.keyInfoArray = $tw.keyboardManager.parseKeyDescriptors(this.key);\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\nexports.keyboard = KeyboardWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/link.js": {
"title": "$:/core/modules/widgets/link.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/link.js\ntype: application/javascript\nmodule-type: widget\n\nLink widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar LinkWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nLinkWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nLinkWidget.prototype.render = function(parent,nextSibling) {\n\t// Save the parent dom node\n\tthis.parentDomNode = parent;\n\t// Compute our attributes\n\tthis.computeAttributes();\n\t// Execute our logic\n\tthis.execute();\n\t// Get the value of the tv-wikilinks configuration macro\n\tvar wikiLinksMacro = this.getVariable(\"tv-wikilinks\"),\n\t\tuseWikiLinks = wikiLinksMacro ? (wikiLinksMacro.trim() !== \"no\") : true,\n\t\tmissingLinksEnabled = !(this.hideMissingLinks && this.isMissing && !this.isShadow);\n\t// Render the link if required\n\tif(useWikiLinks && missingLinksEnabled) {\n\t\tthis.renderLink(parent,nextSibling);\n\t} else {\n\t\t// Just insert the link text\n\t\tvar domNode = this.document.createElement(\"span\");\n\t\tparent.insertBefore(domNode,nextSibling);\n\t\tthis.renderChildren(domNode,null);\n\t\tthis.domNodes.push(domNode);\n\t}\n};\n\n/*\nRender this widget into the DOM\n*/\nLinkWidget.prototype.renderLink = function(parent,nextSibling) {\n\tvar self = this;\n\t// Sanitise the specified tag\n\tvar tag = this.linkTag;\n\tif($tw.config.htmlUnsafeElements.indexOf(tag) !== -1) {\n\t\ttag = \"a\";\n\t}\n\t// Create our element\n\tvar domNode = this.document.createElement(tag);\n\t// Assign classes\n\tvar classes = [];\n\tif(this.overrideClasses === undefined) {\n\t\tclasses.push(\"tc-tiddlylink\");\n\t\tif(this.isShadow) {\n\t\t\tclasses.push(\"tc-tiddlylink-shadow\");\n\t\t}\n\t\tif(this.isMissing && !this.isShadow) {\n\t\t\tclasses.push(\"tc-tiddlylink-missing\");\n\t\t} else {\n\t\t\tif(!this.isMissing) {\n\t\t\t\tclasses.push(\"tc-tiddlylink-resolves\");\n\t\t\t}\n\t\t}\n\t\tif(this.linkClasses) {\n\t\t\tclasses.push(this.linkClasses);\t\t\t\n\t\t}\n\t} else if(this.overrideClasses !== \"\") {\n\t\tclasses.push(this.overrideClasses)\n\t}\n\tif(classes.length > 0) {\n\t\tdomNode.setAttribute(\"class\",classes.join(\" \"));\n\t}\n\t// Set an href\n\tvar wikilinkTransformFilter = this.getVariable(\"tv-filter-export-link\"),\n\t\twikiLinkText;\n\tif(wikilinkTransformFilter) {\n\t\t// Use the filter to construct the href\n\t\twikiLinkText = this.wiki.filterTiddlers(wikilinkTransformFilter,this,function(iterator) {\n\t\t\titerator(self.wiki.getTiddler(self.to),self.to)\n\t\t})[0];\n\t} else {\n\t\t// Expand the tv-wikilink-template variable to construct the href\n\t\tvar wikiLinkTemplateMacro = this.getVariable(\"tv-wikilink-template\"),\n\t\t\twikiLinkTemplate = wikiLinkTemplateMacro ? wikiLinkTemplateMacro.trim() : \"#$uri_encoded$\";\n\t\twikiLinkText = $tw.utils.replaceString(wikiLinkTemplate,\"$uri_encoded$\",encodeURIComponent(this.to));\n\t\twikiLinkText = $tw.utils.replaceString(wikiLinkText,\"$uri_doubleencoded$\",encodeURIComponent(encodeURIComponent(this.to)));\n\t}\n\t// Override with the value of tv-get-export-link if defined\n\twikiLinkText = this.getVariable(\"tv-get-export-link\",{params: [{name: \"to\",value: this.to}],defaultValue: wikiLinkText});\n\tif(tag === \"a\") {\n\t\tdomNode.setAttribute(\"href\",wikiLinkText);\n\t}\n\t// Set the tabindex\n\tif(this.tabIndex) {\n\t\tdomNode.setAttribute(\"tabindex\",this.tabIndex);\n\t}\n\t// Set the tooltip\n\t// HACK: Performance issues with re-parsing the tooltip prevent us defaulting the tooltip to \"<$transclude field='tooltip'><$transclude field='title'/></$transclude>\"\n\tvar tooltipWikiText = this.tooltip || this.getVariable(\"tv-wikilink-tooltip\");\n\tif(tooltipWikiText) {\n\t\tvar tooltipText = this.wiki.renderText(\"text/plain\",\"text/vnd.tiddlywiki\",tooltipWikiText,{\n\t\t\t\tparseAsInline: true,\n\t\t\t\tvariables: {\n\t\t\t\t\tcurrentTiddler: this.to\n\t\t\t\t},\n\t\t\t\tparentWidget: this\n\t\t\t});\n\t\tdomNode.setAttribute(\"title\",tooltipText);\n\t}\n\tif(this[\"aria-label\"]) {\n\t\tdomNode.setAttribute(\"aria-label\",this[\"aria-label\"]);\n\t}\n\t// Add a click event handler\n\t$tw.utils.addEventListeners(domNode,[\n\t\t{name: \"click\", handlerObject: this, handlerMethod: \"handleClickEvent\"},\n\t]);\n\t// Make the link draggable if required\n\tif(this.draggable === \"yes\") {\n\t\t$tw.utils.makeDraggable({\n\t\t\tdomNode: domNode,\n\t\t\tdragTiddlerFn: function() {return self.to;},\n\t\t\twidget: this\n\t\t});\n\t}\n\t// Insert the link into the DOM and render any children\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.renderChildren(domNode,null);\n\tthis.domNodes.push(domNode);\n};\n\nLinkWidget.prototype.handleClickEvent = function(event) {\n\t// Send the click on its way as a navigate event\n\tvar bounds = this.domNodes[0].getBoundingClientRect();\n\tthis.dispatchEvent({\n\t\ttype: \"tm-navigate\",\n\t\tnavigateTo: this.to,\n\t\tnavigateFromTitle: this.getVariable(\"storyTiddler\"),\n\t\tnavigateFromNode: this,\n\t\tnavigateFromClientRect: { top: bounds.top, left: bounds.left, width: bounds.width, right: bounds.right, bottom: bounds.bottom, height: bounds.height\n\t\t},\n\t\tnavigateSuppressNavigation: event.metaKey || event.ctrlKey || (event.button === 1),\n\t\tmetaKey: event.metaKey,\n\t\tctrlKey: event.ctrlKey,\n\t\taltKey: event.altKey,\n\t\tshiftKey: event.shiftKey\n\t});\n\tif(this.domNodes[0].hasAttribute(\"href\")) {\n\t\tevent.preventDefault();\n\t}\n\tevent.stopPropagation();\n\treturn false;\n};\n\n/*\nCompute the internal state of the widget\n*/\nLinkWidget.prototype.execute = function() {\n\t// Pick up our attributes\n\tthis.to = this.getAttribute(\"to\",this.getVariable(\"currentTiddler\"));\n\tthis.tooltip = this.getAttribute(\"tooltip\");\n\tthis[\"aria-label\"] = this.getAttribute(\"aria-label\");\n\tthis.linkClasses = this.getAttribute(\"class\");\n\tthis.overrideClasses = this.getAttribute(\"overrideClass\");\n\tthis.tabIndex = this.getAttribute(\"tabindex\");\n\tthis.draggable = this.getAttribute(\"draggable\",\"yes\");\n\tthis.linkTag = this.getAttribute(\"tag\",\"a\");\n\t// Determine the link characteristics\n\tthis.isMissing = !this.wiki.tiddlerExists(this.to);\n\tthis.isShadow = this.wiki.isShadowTiddler(this.to);\n\tthis.hideMissingLinks = (this.getVariable(\"tv-show-missing-links\") || \"yes\") === \"no\";\n\t// Make the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nLinkWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.to || changedTiddlers[this.to] || changedAttributes[\"aria-label\"] || changedAttributes.tooltip) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\nexports.link = LinkWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/linkcatcher.js": {
"title": "$:/core/modules/widgets/linkcatcher.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/linkcatcher.js\ntype: application/javascript\nmodule-type: widget\n\nLinkcatcher widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar LinkCatcherWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n\tthis.addEventListeners([\n\t\t{type: \"tm-navigate\", handler: \"handleNavigateEvent\"}\n\t]);\n};\n\n/*\nInherit from the base widget class\n*/\nLinkCatcherWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nLinkCatcherWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nLinkCatcherWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.catchTo = this.getAttribute(\"to\");\n\tthis.catchMessage = this.getAttribute(\"message\");\n\tthis.catchSet = this.getAttribute(\"set\");\n\tthis.catchSetTo = this.getAttribute(\"setTo\");\n\tthis.catchActions = this.getAttribute(\"actions\");\n\t// Construct the child widgets\n\tthis.makeChildWidgets();\n\t// When executing actions we avoid trapping navigate events, so that we don't trigger ourselves recursively\n\tthis.executingActions = false;\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nLinkCatcherWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.to || changedAttributes.message || changedAttributes.set || changedAttributes.setTo) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\t\t\n\t}\n};\n\n/*\nHandle a tm-navigate event\n*/\nLinkCatcherWidget.prototype.handleNavigateEvent = function(event) {\n\tif(!this.executingActions) {\n\t\t// Execute the actions\n\t\tif(this.catchTo) {\n\t\t\tthis.wiki.setTextReference(this.catchTo,event.navigateTo,this.getVariable(\"currentTiddler\"));\n\t\t}\n\t\tif(this.catchMessage && this.parentWidget) {\n\t\t\tthis.parentWidget.dispatchEvent({\n\t\t\t\ttype: this.catchMessage,\n\t\t\t\tparam: event.navigateTo,\n\t\t\t\tnavigateTo: event.navigateTo\n\t\t\t});\n\t\t}\n\t\tif(this.catchSet) {\n\t\t\tvar tiddler = this.wiki.getTiddler(this.catchSet);\n\t\t\tthis.wiki.addTiddler(new $tw.Tiddler(tiddler,{title: this.catchSet, text: this.catchSetTo}));\n\t\t}\n\t\tif(this.catchActions) {\n\t\t\tthis.executingActions = true;\n\t\t\tthis.invokeActionString(this.catchActions,this,event,{navigateTo: event.navigateTo});\n\t\t\tthis.executingActions = false;\n\t\t}\n\t} else {\n\t\t// This is a navigate event generated by the actions of this linkcatcher, so we don't trap it again, but just pass it to the parent\n\t\tthis.parentWidget.dispatchEvent({\n\t\t\ttype: \"tm-navigate\",\n\t\t\tparam: event.navigateTo,\n\t\t\tnavigateTo: event.navigateTo\n\t\t});\n\t}\n\treturn false;\n};\n\nexports.linkcatcher = LinkCatcherWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/list.js": {
"title": "$:/core/modules/widgets/list.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/list.js\ntype: application/javascript\nmodule-type: widget\n\nList and list item widgets\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\n/*\nThe list widget creates list element sub-widgets that reach back into the list widget for their configuration\n*/\n\nvar ListWidget = function(parseTreeNode,options) {\n\t// Initialise the storyviews if they've not been done already\n\tif(!this.storyViews) {\n\t\tListWidget.prototype.storyViews = {};\n\t\t$tw.modules.applyMethods(\"storyview\",this.storyViews);\n\t}\n\t// Main initialisation inherited from widget.js\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nListWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nListWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n\t// Construct the storyview\n\tvar StoryView = this.storyViews[this.storyViewName];\n\tif(this.storyViewName && !StoryView) {\n\t\tStoryView = this.storyViews[\"classic\"];\n\t}\n\tif(StoryView && !this.document.isTiddlyWikiFakeDom) {\n\t\tthis.storyview = new StoryView(this);\n\t} else {\n\t\tthis.storyview = null;\n\t}\n};\n\n/*\nCompute the internal state of the widget\n*/\nListWidget.prototype.execute = function() {\n\t// Get our attributes\n\tthis.template = this.getAttribute(\"template\");\n\tthis.editTemplate = this.getAttribute(\"editTemplate\");\n\tthis.variableName = this.getAttribute(\"variable\",\"currentTiddler\");\n\tthis.storyViewName = this.getAttribute(\"storyview\");\n\tthis.historyTitle = this.getAttribute(\"history\");\n\t// Compose the list elements\n\tthis.list = this.getTiddlerList();\n\tvar members = [],\n\t\tself = this;\n\t// Check for an empty list\n\tif(this.list.length === 0) {\n\t\tmembers = this.getEmptyMessage();\n\t} else {\n\t\t$tw.utils.each(this.list,function(title,index) {\n\t\t\tmembers.push(self.makeItemTemplate(title));\n\t\t});\n\t}\n\t// Construct the child widgets\n\tthis.makeChildWidgets(members);\n\t// Clear the last history\n\tthis.history = [];\n};\n\nListWidget.prototype.getTiddlerList = function() {\n\tvar defaultFilter = \"[!is[system]sort[title]]\";\n\treturn this.wiki.filterTiddlers(this.getAttribute(\"filter\",defaultFilter),this);\n};\n\nListWidget.prototype.getEmptyMessage = function() {\n\tvar emptyMessage = this.getAttribute(\"emptyMessage\",\"\"),\n\t\tparser = this.wiki.parseText(\"text/vnd.tiddlywiki\",emptyMessage,{parseAsInline: true});\n\tif(parser) {\n\t\treturn parser.tree;\n\t} else {\n\t\treturn [];\n\t}\n};\n\n/*\nCompose the template for a list item\n*/\nListWidget.prototype.makeItemTemplate = function(title) {\n\t// Check if the tiddler is a draft\n\tvar tiddler = this.wiki.getTiddler(title),\n\t\tisDraft = tiddler && tiddler.hasField(\"draft.of\"),\n\t\ttemplate = this.template,\n\t\ttemplateTree;\n\tif(isDraft && this.editTemplate) {\n\t\ttemplate = this.editTemplate;\n\t}\n\t// Compose the transclusion of the template\n\tif(template) {\n\t\ttemplateTree = [{type: \"transclude\", attributes: {tiddler: {type: \"string\", value: template}}}];\n\t} else {\n\t\tif(this.parseTreeNode.children && this.parseTreeNode.children.length > 0) {\n\t\t\ttemplateTree = this.parseTreeNode.children;\n\t\t} else {\n\t\t\t// Default template is a link to the title\n\t\t\ttemplateTree = [{type: \"element\", tag: this.parseTreeNode.isBlock ? \"div\" : \"span\", children: [{type: \"link\", attributes: {to: {type: \"string\", value: title}}, children: [\n\t\t\t\t\t{type: \"text\", text: title}\n\t\t\t]}]}];\n\t\t}\n\t}\n\t// Return the list item\n\treturn {type: \"listitem\", itemTitle: title, variableName: this.variableName, children: templateTree};\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nListWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes(),\n\t\tresult;\n\t// Call the storyview\n\tif(this.storyview && this.storyview.refreshStart) {\n\t\tthis.storyview.refreshStart(changedTiddlers,changedAttributes);\n\t}\n\t// Completely refresh if any of our attributes have changed\n\tif(changedAttributes.filter || changedAttributes.template || changedAttributes.editTemplate || changedAttributes.emptyMessage || changedAttributes.storyview || changedAttributes.history) {\n\t\tthis.refreshSelf();\n\t\tresult = true;\n\t} else {\n\t\t// Handle any changes to the list\n\t\tresult = this.handleListChanges(changedTiddlers);\n\t\t// Handle any changes to the history stack\n\t\tif(this.historyTitle && changedTiddlers[this.historyTitle]) {\n\t\t\tthis.handleHistoryChanges();\n\t\t}\n\t}\n\t// Call the storyview\n\tif(this.storyview && this.storyview.refreshEnd) {\n\t\tthis.storyview.refreshEnd(changedTiddlers,changedAttributes);\n\t}\n\treturn result;\n};\n\n/*\nHandle any changes to the history list\n*/\nListWidget.prototype.handleHistoryChanges = function() {\n\t// Get the history data\n\tvar newHistory = this.wiki.getTiddlerDataCached(this.historyTitle,[]);\n\t// Ignore any entries of the history that match the previous history\n\tvar entry = 0;\n\twhile(entry < newHistory.length && entry < this.history.length && newHistory[entry].title === this.history[entry].title) {\n\t\tentry++;\n\t}\n\t// Navigate forwards to each of the new tiddlers\n\twhile(entry < newHistory.length) {\n\t\tif(this.storyview && this.storyview.navigateTo) {\n\t\t\tthis.storyview.navigateTo(newHistory[entry]);\n\t\t}\n\t\tentry++;\n\t}\n\t// Update the history\n\tthis.history = newHistory;\n};\n\n/*\nProcess any changes to the list\n*/\nListWidget.prototype.handleListChanges = function(changedTiddlers) {\n\t// Get the new list\n\tvar prevList = this.list;\n\tthis.list = this.getTiddlerList();\n\t// Check for an empty list\n\tif(this.list.length === 0) {\n\t\t// Check if it was empty before\n\t\tif(prevList.length === 0) {\n\t\t\t// If so, just refresh the empty message\n\t\t\treturn this.refreshChildren(changedTiddlers);\n\t\t} else {\n\t\t\t// Replace the previous content with the empty message\n\t\t\tfor(t=this.children.length-1; t>=0; t--) {\n\t\t\t\tthis.removeListItem(t);\n\t\t\t}\n\t\t\tvar nextSibling = this.findNextSiblingDomNode();\n\t\t\tthis.makeChildWidgets(this.getEmptyMessage());\n\t\t\tthis.renderChildren(this.parentDomNode,nextSibling);\n\t\t\treturn true;\n\t\t}\n\t} else {\n\t\t// If the list was empty then we need to remove the empty message\n\t\tif(prevList.length === 0) {\n\t\t\tthis.removeChildDomNodes();\n\t\t\tthis.children = [];\n\t\t}\n\t\t// Cycle through the list, inserting and removing list items as needed\n\t\tvar hasRefreshed = false;\n\t\tfor(var t=0; t<this.list.length; t++) {\n\t\t\tvar index = this.findListItem(t,this.list[t]);\n\t\t\tif(index === undefined) {\n\t\t\t\t// The list item must be inserted\n\t\t\t\tthis.insertListItem(t,this.list[t]);\n\t\t\t\thasRefreshed = true;\n\t\t\t} else {\n\t\t\t\t// There are intervening list items that must be removed\n\t\t\t\tfor(var n=index-1; n>=t; n--) {\n\t\t\t\t\tthis.removeListItem(n);\n\t\t\t\t\thasRefreshed = true;\n\t\t\t\t}\n\t\t\t\t// Refresh the item we're reusing\n\t\t\t\tvar refreshed = this.children[t].refresh(changedTiddlers);\n\t\t\t\thasRefreshed = hasRefreshed || refreshed;\n\t\t\t}\n\t\t}\n\t\t// Remove any left over items\n\t\tfor(t=this.children.length-1; t>=this.list.length; t--) {\n\t\t\tthis.removeListItem(t);\n\t\t\thasRefreshed = true;\n\t\t}\n\t\treturn hasRefreshed;\n\t}\n};\n\n/*\nFind the list item with a given title, starting from a specified position\n*/\nListWidget.prototype.findListItem = function(startIndex,title) {\n\twhile(startIndex < this.children.length) {\n\t\tif(this.children[startIndex].parseTreeNode.itemTitle === title) {\n\t\t\treturn startIndex;\n\t\t}\n\t\tstartIndex++;\n\t}\n\treturn undefined;\n};\n\n/*\nInsert a new list item at the specified index\n*/\nListWidget.prototype.insertListItem = function(index,title) {\n\t// Create, insert and render the new child widgets\n\tvar widget = this.makeChildWidget(this.makeItemTemplate(title));\n\twidget.parentDomNode = this.parentDomNode; // Hack to enable findNextSiblingDomNode() to work\n\tthis.children.splice(index,0,widget);\n\tvar nextSibling = widget.findNextSiblingDomNode();\n\twidget.render(this.parentDomNode,nextSibling);\n\t// Animate the insertion if required\n\tif(this.storyview && this.storyview.insert) {\n\t\tthis.storyview.insert(widget);\n\t}\n\treturn true;\n};\n\n/*\nRemove the specified list item\n*/\nListWidget.prototype.removeListItem = function(index) {\n\tvar widget = this.children[index];\n\t// Animate the removal if required\n\tif(this.storyview && this.storyview.remove) {\n\t\tthis.storyview.remove(widget);\n\t} else {\n\t\twidget.removeChildDomNodes();\n\t}\n\t// Remove the child widget\n\tthis.children.splice(index,1);\n};\n\nexports.list = ListWidget;\n\nvar ListItemWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nListItemWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nListItemWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nListItemWidget.prototype.execute = function() {\n\t// Set the current list item title\n\tthis.setVariable(this.parseTreeNode.variableName,this.parseTreeNode.itemTitle);\n\t// Construct the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nListItemWidget.prototype.refresh = function(changedTiddlers) {\n\treturn this.refreshChildren(changedTiddlers);\n};\n\nexports.listitem = ListItemWidget;\n\n})();",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/macrocall.js": {
"title": "$:/core/modules/widgets/macrocall.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/macrocall.js\ntype: application/javascript\nmodule-type: widget\n\nMacrocall widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar MacroCallWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nMacroCallWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nMacroCallWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nMacroCallWidget.prototype.execute = function() {\n\t// Get the parse type if specified\n\tthis.parseType = this.getAttribute(\"$type\",\"text/vnd.tiddlywiki\");\n\tthis.renderOutput = this.getAttribute(\"$output\",\"text/html\");\n\t// Merge together the parameters specified in the parse tree with the specified attributes\n\tvar params = this.parseTreeNode.params ? this.parseTreeNode.params.slice(0) : [];\n\t$tw.utils.each(this.attributes,function(attribute,name) {\n\t\tif(name.charAt(0) !== \"$\") {\n\t\t\tparams.push({name: name, value: attribute});\t\t\t\n\t\t}\n\t});\n\t// Get the macro value\n\tvar macroName = this.parseTreeNode.name || this.getAttribute(\"$name\"),\n\t\tvariableInfo = this.getVariableInfo(macroName,{params: params}),\n\t\ttext = variableInfo.text,\n\t\tparseTreeNodes;\n\t// Are we rendering to HTML?\n\tif(this.renderOutput === \"text/html\") {\n\t\t// If so we'll return the parsed macro\n\t\tvar parser = this.wiki.parseText(this.parseType,text,\n\t\t\t\t\t\t\t{parseAsInline: !this.parseTreeNode.isBlock});\n\t\tparseTreeNodes = parser ? parser.tree : [];\n\t\t// Wrap the parse tree in a vars widget assigning the parameters to variables named \"__paramname__\"\n\t\tvar attributes = {};\n\t\t$tw.utils.each(variableInfo.params,function(param) {\n\t\t\tvar name = \"__\" + param.name + \"__\";\n\t\t\tattributes[name] = {\n\t\t\t\tname: name,\n\t\t\t\ttype: \"string\",\n\t\t\t\tvalue: param.value\n\t\t\t};\n\t\t});\n\t\tparseTreeNodes = [{\n\t\t\ttype: \"vars\",\n\t\t\tattributes: attributes,\n\t\t\tchildren: parseTreeNodes\n\t\t}];\n\t} else {\n\t\t// Otherwise, we'll render the text\n\t\tvar plainText = this.wiki.renderText(\"text/plain\",this.parseType,text,{parentWidget: this});\n\t\tparseTreeNodes = [{type: \"text\", text: plainText}];\n\t}\n\t// Construct the child widgets\n\tthis.makeChildWidgets(parseTreeNodes);\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nMacroCallWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif($tw.utils.count(changedAttributes) > 0) {\n\t\t// Rerender ourselves\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\n\t}\n};\n\nexports.macrocall = MacroCallWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/navigator.js": {
"title": "$:/core/modules/widgets/navigator.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/navigator.js\ntype: application/javascript\nmodule-type: widget\n\nNavigator widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar IMPORT_TITLE = \"$:/Import\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar NavigatorWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n\tthis.addEventListeners([\n\t\t{type: \"tm-navigate\", handler: \"handleNavigateEvent\"},\n\t\t{type: \"tm-edit-tiddler\", handler: \"handleEditTiddlerEvent\"},\n\t\t{type: \"tm-delete-tiddler\", handler: \"handleDeleteTiddlerEvent\"},\n\t\t{type: \"tm-save-tiddler\", handler: \"handleSaveTiddlerEvent\"},\n\t\t{type: \"tm-cancel-tiddler\", handler: \"handleCancelTiddlerEvent\"},\n\t\t{type: \"tm-close-tiddler\", handler: \"handleCloseTiddlerEvent\"},\n\t\t{type: \"tm-close-all-tiddlers\", handler: \"handleCloseAllTiddlersEvent\"},\n\t\t{type: \"tm-close-other-tiddlers\", handler: \"handleCloseOtherTiddlersEvent\"},\n\t\t{type: \"tm-new-tiddler\", handler: \"handleNewTiddlerEvent\"},\n\t\t{type: \"tm-import-tiddlers\", handler: \"handleImportTiddlersEvent\"},\n\t\t{type: \"tm-perform-import\", handler: \"handlePerformImportEvent\"},\n\t\t{type: \"tm-fold-tiddler\", handler: \"handleFoldTiddlerEvent\"},\n\t\t{type: \"tm-fold-other-tiddlers\", handler: \"handleFoldOtherTiddlersEvent\"},\n\t\t{type: \"tm-fold-all-tiddlers\", handler: \"handleFoldAllTiddlersEvent\"},\n\t\t{type: \"tm-unfold-all-tiddlers\", handler: \"handleUnfoldAllTiddlersEvent\"},\n\t\t{type: \"tm-rename-tiddler\", handler: \"handleRenameTiddlerEvent\"}\n\t]);\n};\n\n/*\nInherit from the base widget class\n*/\nNavigatorWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nNavigatorWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nNavigatorWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.storyTitle = this.getAttribute(\"story\");\n\tthis.historyTitle = this.getAttribute(\"history\");\n\tthis.setVariable(\"tv-story-list\",this.storyTitle);\n\tthis.setVariable(\"tv-history-list\",this.historyTitle);\n\t// Construct the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nNavigatorWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.story || changedAttributes.history) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\n\t}\n};\n\nNavigatorWidget.prototype.getStoryList = function() {\n\treturn this.storyTitle ? this.wiki.getTiddlerList(this.storyTitle) : null;\n};\n\nNavigatorWidget.prototype.saveStoryList = function(storyList) {\n\tvar storyTiddler = this.wiki.getTiddler(this.storyTitle);\n\tthis.wiki.addTiddler(new $tw.Tiddler(\n\t\t{title: this.storyTitle},\n\t\tstoryTiddler,\n\t\t{list: storyList}\n\t));\n};\n\nNavigatorWidget.prototype.removeTitleFromStory = function(storyList,title) {\n\tvar p = storyList.indexOf(title);\n\twhile(p !== -1) {\n\t\tstoryList.splice(p,1);\n\t\tp = storyList.indexOf(title);\n\t}\n};\n\nNavigatorWidget.prototype.replaceFirstTitleInStory = function(storyList,oldTitle,newTitle) {\n\tvar pos = storyList.indexOf(oldTitle);\n\tif(pos !== -1) {\n\t\tstoryList[pos] = newTitle;\n\t\tdo {\n\t\t\tpos = storyList.indexOf(oldTitle,pos + 1);\n\t\t\tif(pos !== -1) {\n\t\t\t\tstoryList.splice(pos,1);\n\t\t\t}\n\t\t} while(pos !== -1);\n\t} else {\n\t\tstoryList.splice(0,0,newTitle);\n\t}\n};\n\nNavigatorWidget.prototype.addToStory = function(title,fromTitle) {\n\tthis.wiki.addToStory(title,fromTitle,this.storyTitle,{openLinkFromInsideRiver: this.getAttribute(\"openLinkFromInsideRiver\",\"top\"),openLinkFromOutsideRiver: this.getAttribute(\"openLinkFromOutsideRiver\",\"top\")});\n};\n\n/*\nAdd a new record to the top of the history stack\ntitle: a title string or an array of title strings\nfromPageRect: page coordinates of the origin of the navigation\n*/\nNavigatorWidget.prototype.addToHistory = function(title,fromPageRect) {\n\tthis.wiki.addToHistory(title,fromPageRect,this.historyTitle);\n};\n\n/*\nHandle a tm-navigate event\n*/\nNavigatorWidget.prototype.handleNavigateEvent = function(event) {\n\tevent = $tw.hooks.invokeHook(\"th-navigating\",event);\n\tif(event.navigateTo) {\n\t\tthis.addToStory(event.navigateTo,event.navigateFromTitle);\n\t\tif(!event.navigateSuppressNavigation) {\n\t\t\tthis.addToHistory(event.navigateTo,event.navigateFromClientRect);\n\t\t}\n\t}\n\treturn false;\n};\n\n// Close a specified tiddler\nNavigatorWidget.prototype.handleCloseTiddlerEvent = function(event) {\n\tvar title = event.param || event.tiddlerTitle,\n\t\tstoryList = this.getStoryList();\n\t// Look for tiddlers with this title to close\n\tthis.removeTitleFromStory(storyList,title);\n\tthis.saveStoryList(storyList);\n\treturn false;\n};\n\n// Close all tiddlers\nNavigatorWidget.prototype.handleCloseAllTiddlersEvent = function(event) {\n\tthis.saveStoryList([]);\n\treturn false;\n};\n\n// Close other tiddlers\nNavigatorWidget.prototype.handleCloseOtherTiddlersEvent = function(event) {\n\tvar title = event.param || event.tiddlerTitle;\n\tthis.saveStoryList([title]);\n\treturn false;\n};\n\n// Place a tiddler in edit mode\nNavigatorWidget.prototype.handleEditTiddlerEvent = function(event) {\n\tvar editTiddler = $tw.hooks.invokeHook(\"th-editing-tiddler\",event);\n\tif(!editTiddler) {\n\t\treturn false;\n\t}\n\tvar self = this;\n\tfunction isUnmodifiedShadow(title) {\n\t\treturn self.wiki.isShadowTiddler(title) && !self.wiki.tiddlerExists(title);\n\t}\n\tfunction confirmEditShadow(title) {\n\t\treturn confirm($tw.language.getString(\n\t\t\t\"ConfirmEditShadowTiddler\",\n\t\t\t{variables:\n\t\t\t\t{title: title}\n\t\t\t}\n\t\t));\n\t}\n\tvar title = event.param || event.tiddlerTitle;\n\tif(isUnmodifiedShadow(title) && !confirmEditShadow(title)) {\n\t\treturn false;\n\t}\n\t// Replace the specified tiddler with a draft in edit mode\n\tvar draftTiddler = this.makeDraftTiddler(title);\n\t// Update the story and history if required\n\tif(!event.paramObject || event.paramObject.suppressNavigation !== \"yes\") {\n\t\tvar draftTitle = draftTiddler.fields.title,\n\t\t\tstoryList = this.getStoryList();\n\t\tthis.removeTitleFromStory(storyList,draftTitle);\n\t\tthis.replaceFirstTitleInStory(storyList,title,draftTitle);\n\t\tthis.addToHistory(draftTitle,event.navigateFromClientRect);\n\t\tthis.saveStoryList(storyList);\n\t\treturn false;\n\t}\n};\n\n// Delete a tiddler\nNavigatorWidget.prototype.handleDeleteTiddlerEvent = function(event) {\n\t// Get the tiddler we're deleting\n\tvar title = event.param || event.tiddlerTitle,\n\t\ttiddler = this.wiki.getTiddler(title),\n\t\tstoryList = this.getStoryList(),\n\t\toriginalTitle = tiddler ? tiddler.fields[\"draft.of\"] : \"\",\n\t\toriginalTiddler = originalTitle ? this.wiki.getTiddler(originalTitle) : undefined,\n\t\tconfirmationTitle;\n\tif(!tiddler) {\n\t\treturn false;\n\t}\n\t// Check if the tiddler we're deleting is in draft mode\n\tif(originalTitle) {\n\t\t// If so, we'll prompt for confirmation referencing the original tiddler\n\t\tconfirmationTitle = originalTitle;\n\t} else {\n\t\t// If not a draft, then prompt for confirmation referencing the specified tiddler\n\t\tconfirmationTitle = title;\n\t}\n\t// Seek confirmation\n\tif((this.wiki.getTiddler(originalTitle) || (tiddler.fields.text || \"\") !== \"\") && !confirm($tw.language.getString(\n\t\t\t\t\"ConfirmDeleteTiddler\",\n\t\t\t\t{variables:\n\t\t\t\t\t{title: confirmationTitle}\n\t\t\t\t}\n\t\t\t))) {\n\t\treturn false;\n\t}\n\t// Delete the original tiddler\n\tif(originalTitle) {\n\t\tif(originalTiddler) {\n\t\t\t$tw.hooks.invokeHook(\"th-deleting-tiddler\",originalTiddler);\n\t\t}\n\t\tthis.wiki.deleteTiddler(originalTitle);\n\t\tthis.removeTitleFromStory(storyList,originalTitle);\n\t}\n\t// Invoke the hook function and delete this tiddler\n\t$tw.hooks.invokeHook(\"th-deleting-tiddler\",tiddler);\n\tthis.wiki.deleteTiddler(title);\n\t// Remove the closed tiddler from the story\n\tthis.removeTitleFromStory(storyList,title);\n\tthis.saveStoryList(storyList);\n\t// Trigger an autosave\n\t$tw.rootWidget.dispatchEvent({type: \"tm-auto-save-wiki\"});\n\treturn false;\n};\n\n/*\nCreate/reuse the draft tiddler for a given title\n*/\nNavigatorWidget.prototype.makeDraftTiddler = function(targetTitle) {\n\t// See if there is already a draft tiddler for this tiddler\n\tvar draftTitle = this.wiki.findDraft(targetTitle);\n\tif(draftTitle) {\n\t\treturn this.wiki.getTiddler(draftTitle);\n\t}\n\t// Get the current value of the tiddler we're editing\n\tvar tiddler = this.wiki.getTiddler(targetTitle);\n\t// Save the initial value of the draft tiddler\n\tdraftTitle = this.generateDraftTitle(targetTitle);\n\tvar draftTiddler = new $tw.Tiddler(\n\t\t\ttiddler,\n\t\t\t{\n\t\t\t\ttitle: draftTitle,\n\t\t\t\t\"draft.title\": targetTitle,\n\t\t\t\t\"draft.of\": targetTitle\n\t\t\t},\n\t\t\tthis.wiki.getModificationFields()\n\t\t);\n\tthis.wiki.addTiddler(draftTiddler);\n\treturn draftTiddler;\n};\n\n/*\nGenerate a title for the draft of a given tiddler\n*/\nNavigatorWidget.prototype.generateDraftTitle = function(title) {\n\tvar c = 0,\n\t\tdraftTitle,\n\t\tusername = this.wiki.getTiddlerText(\"$:/status/UserName\"),\n\t\tattribution = username ? \" by \" + username : \"\";\n\tdo {\n\t\tdraftTitle = \"Draft \" + (c ? (c + 1) + \" \" : \"\") + \"of '\" + title + \"'\" + attribution;\n\t\tc++;\n\t} while(this.wiki.tiddlerExists(draftTitle));\n\treturn draftTitle;\n};\n\n// Take a tiddler out of edit mode, saving the changes\nNavigatorWidget.prototype.handleSaveTiddlerEvent = function(event) {\n\tvar title = event.param || event.tiddlerTitle,\n\t\ttiddler = this.wiki.getTiddler(title),\n\t\tstoryList = this.getStoryList();\n\t// Replace the original tiddler with the draft\n\tif(tiddler) {\n\t\tvar draftTitle = (tiddler.fields[\"draft.title\"] || \"\").trim(),\n\t\t\tdraftOf = (tiddler.fields[\"draft.of\"] || \"\").trim();\n\t\tif(draftTitle) {\n\t\t\tvar isRename = draftOf !== draftTitle,\n\t\t\t\tisConfirmed = true;\n\t\t\tif(isRename && this.wiki.tiddlerExists(draftTitle)) {\n\t\t\t\tisConfirmed = confirm($tw.language.getString(\n\t\t\t\t\t\"ConfirmOverwriteTiddler\",\n\t\t\t\t\t{variables:\n\t\t\t\t\t\t{title: draftTitle}\n\t\t\t\t\t}\n\t\t\t\t));\n\t\t\t}\n\t\t\tif(isConfirmed) {\n\t\t\t\t// Create the new tiddler and pass it through the th-saving-tiddler hook\n\t\t\t\tvar newTiddler = new $tw.Tiddler(this.wiki.getCreationFields(),tiddler,{\n\t\t\t\t\ttitle: draftTitle,\n\t\t\t\t\t\"draft.title\": undefined,\n\t\t\t\t\t\"draft.of\": undefined\n\t\t\t\t},this.wiki.getModificationFields());\n\t\t\t\tnewTiddler = $tw.hooks.invokeHook(\"th-saving-tiddler\",newTiddler);\n\t\t\t\tthis.wiki.addTiddler(newTiddler);\n\t\t\t\t// If enabled, relink references to renamed tiddler\n\t\t\t\tvar shouldRelink = this.getAttribute(\"relinkOnRename\",\"no\").toLowerCase().trim() === \"yes\";\n\t\t\t\tif(isRename && shouldRelink && this.wiki.tiddlerExists(draftOf)) {\nconsole.log(\"Relinking '\" + draftOf + \"' to '\" + draftTitle + \"'\");\n\t\t\t\t\tthis.wiki.relinkTiddler(draftOf,draftTitle);\n\t\t\t\t}\n\t\t\t\t// Remove the draft tiddler\n\t\t\t\tthis.wiki.deleteTiddler(title);\n\t\t\t\t// Remove the original tiddler if we're renaming it\n\t\t\t\tif(isRename) {\n\t\t\t\t\tthis.wiki.deleteTiddler(draftOf);\n\t\t\t\t}\n\t\t\t\t// #2381 always remove new title & old\n\t\t\t\tthis.removeTitleFromStory(storyList,draftTitle);\n\t\t\t\tthis.removeTitleFromStory(storyList,draftOf);\n\t\t\t\tif(!event.paramObject || event.paramObject.suppressNavigation !== \"yes\") {\n\t\t\t\t\t// Replace the draft in the story with the original\n\t\t\t\t\tthis.replaceFirstTitleInStory(storyList,title,draftTitle);\n\t\t\t\t\tthis.addToHistory(draftTitle,event.navigateFromClientRect);\n\t\t\t\t\tif(draftTitle !== this.storyTitle) {\n\t\t\t\t\t\tthis.saveStoryList(storyList);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Trigger an autosave\n\t\t\t\t$tw.rootWidget.dispatchEvent({type: \"tm-auto-save-wiki\"});\n\t\t\t}\n\t\t}\n\t}\n\treturn false;\n};\n\n// Take a tiddler out of edit mode without saving the changes\nNavigatorWidget.prototype.handleCancelTiddlerEvent = function(event) {\n\tevent = $tw.hooks.invokeHook(\"th-cancelling-tiddler\", event);\n\t// Flip the specified tiddler from draft back to the original\n\tvar draftTitle = event.param || event.tiddlerTitle,\n\t\tdraftTiddler = this.wiki.getTiddler(draftTitle),\n\t\toriginalTitle = draftTiddler && draftTiddler.fields[\"draft.of\"];\n\tif(draftTiddler && originalTitle) {\n\t\t// Ask for confirmation if the tiddler text has changed\n\t\tvar isConfirmed = true,\n\t\t\toriginalTiddler = this.wiki.getTiddler(originalTitle),\n\t\t\tstoryList = this.getStoryList();\n\t\tif(this.wiki.isDraftModified(draftTitle)) {\n\t\t\tisConfirmed = confirm($tw.language.getString(\n\t\t\t\t\"ConfirmCancelTiddler\",\n\t\t\t\t{variables:\n\t\t\t\t\t{title: draftTitle}\n\t\t\t\t}\n\t\t\t));\n\t\t}\n\t\t// Remove the draft tiddler\n\t\tif(isConfirmed) {\n\t\t\tthis.wiki.deleteTiddler(draftTitle);\n\t\t\tif(!event.paramObject || event.paramObject.suppressNavigation !== \"yes\") {\n\t\t\t\tif(originalTiddler) {\n\t\t\t\t\tthis.replaceFirstTitleInStory(storyList,draftTitle,originalTitle);\n\t\t\t\t\tthis.addToHistory(originalTitle,event.navigateFromClientRect);\n\t\t\t\t} else {\n\t\t\t\t\tthis.removeTitleFromStory(storyList,draftTitle);\n\t\t\t\t}\n\t\t\t\tthis.saveStoryList(storyList);\n\t\t\t}\n\t\t}\n\t}\n\treturn false;\n};\n\n// Create a new draft tiddler\n// event.param can either be the title of a template tiddler, or a hashmap of fields.\n//\n// The title of the newly created tiddler follows these rules:\n// * If a hashmap was used and a title field was specified, use that title\n// * If a hashmap was used without a title field, use a default title, if necessary making it unique with a numeric suffix\n// * If a template tiddler was used, use the title of the template, if necessary making it unique with a numeric suffix\n//\n// If a draft of the target tiddler already exists then it is reused\nNavigatorWidget.prototype.handleNewTiddlerEvent = function(event) {\n\tevent = $tw.hooks.invokeHook(\"th-new-tiddler\", event);\n\t// Get the story details\n\tvar storyList = this.getStoryList(),\n\t\ttemplateTiddler, additionalFields, title, draftTitle, existingTiddler;\n\t// Get the template tiddler (if any)\n\tif(typeof event.param === \"string\") {\n\t\t// Get the template tiddler\n\t\ttemplateTiddler = this.wiki.getTiddler(event.param);\n\t\t// Generate a new title\n\t\ttitle = this.wiki.generateNewTitle(event.param || $tw.language.getString(\"DefaultNewTiddlerTitle\"));\n\t}\n\t// Get the specified additional fields\n\tif(typeof event.paramObject === \"object\") {\n\t\tadditionalFields = event.paramObject;\n\t}\n\tif(typeof event.param === \"object\") { // Backwards compatibility with 5.1.3\n\t\tadditionalFields = event.param;\n\t}\n\tif(additionalFields && additionalFields.title) {\n\t\ttitle = additionalFields.title;\n\t}\n\t// Make a copy of the additional fields excluding any blank ones\n\tvar filteredAdditionalFields = $tw.utils.extend({},additionalFields);\n\tObject.keys(filteredAdditionalFields).forEach(function(fieldName) {\n\t\tif(filteredAdditionalFields[fieldName] === \"\") {\n\t\t\tdelete filteredAdditionalFields[fieldName];\n\t\t}\n\t});\n\t// Generate a title if we don't have one\n\ttitle = title || this.wiki.generateNewTitle($tw.language.getString(\"DefaultNewTiddlerTitle\"));\n\t// Find any existing draft for this tiddler\n\tdraftTitle = this.wiki.findDraft(title);\n\t// Pull in any existing tiddler\n\tif(draftTitle) {\n\t\texistingTiddler = this.wiki.getTiddler(draftTitle);\n\t} else {\n\t\tdraftTitle = this.generateDraftTitle(title);\n\t\texistingTiddler = this.wiki.getTiddler(title);\n\t}\n\t// Merge the tags\n\tvar mergedTags = [];\n\tif(existingTiddler && existingTiddler.fields.tags) {\n\t\t$tw.utils.pushTop(mergedTags,existingTiddler.fields.tags);\n\t}\n\tif(additionalFields && additionalFields.tags) {\n\t\t// Merge tags\n\t\tmergedTags = $tw.utils.pushTop(mergedTags,$tw.utils.parseStringArray(additionalFields.tags));\n\t}\n\tif(templateTiddler && templateTiddler.fields.tags) {\n\t\t// Merge tags\n\t\tmergedTags = $tw.utils.pushTop(mergedTags,templateTiddler.fields.tags);\n\t}\n\t// Save the draft tiddler\n\tvar draftTiddler = new $tw.Tiddler({\n\t\t\ttext: \"\",\n\t\t\t\"draft.title\": title\n\t\t},\n\t\ttemplateTiddler,\n\t\tadditionalFields,\n\t\tthis.wiki.getCreationFields(),\n\t\texistingTiddler,\n\t\tfilteredAdditionalFields,\n\t\t{\n\t\t\ttitle: draftTitle,\n\t\t\t\"draft.of\": title,\n\t\t\ttags: mergedTags\n\t\t},this.wiki.getModificationFields());\n\tthis.wiki.addTiddler(draftTiddler);\n\t// Update the story to insert the new draft at the top and remove any existing tiddler\n\tif(storyList.indexOf(draftTitle) === -1) {\n\t\tvar slot = storyList.indexOf(event.navigateFromTitle);\n\t\tif(slot === -1) {\n\t\t\tslot = this.getAttribute(\"openLinkFromOutsideRiver\",\"top\") === \"bottom\" ? storyList.length - 1 : slot;\n\t\t}\n\t\tstoryList.splice(slot + 1,0,draftTitle);\n\t}\n\tif(storyList.indexOf(title) !== -1) {\n\t\tstoryList.splice(storyList.indexOf(title),1);\n\t}\n\tthis.saveStoryList(storyList);\n\t// Add a new record to the top of the history stack\n\tthis.addToHistory(draftTitle);\n\treturn false;\n};\n\n// Import JSON tiddlers into a pending import tiddler\nNavigatorWidget.prototype.handleImportTiddlersEvent = function(event) {\n\t// Get the tiddlers\n\tvar tiddlers = [];\n\ttry {\n\t\ttiddlers = JSON.parse(event.param);\n\t} catch(e) {\n\t}\n\t// Get the current $:/Import tiddler\n\tvar importTiddler = this.wiki.getTiddler(IMPORT_TITLE),\n\t\timportData = this.wiki.getTiddlerData(IMPORT_TITLE,{}),\n\t\tnewFields = new Object({\n\t\t\ttitle: IMPORT_TITLE,\n\t\t\ttype: \"application/json\",\n\t\t\t\"plugin-type\": \"import\",\n\t\t\t\"status\": \"pending\"\n\t\t}),\n\t\tincomingTiddlers = [];\n\t// Process each tiddler\n\timportData.tiddlers = importData.tiddlers || {};\n\t$tw.utils.each(tiddlers,function(tiddlerFields) {\n\t\ttiddlerFields.title = $tw.utils.trim(tiddlerFields.title);\n\t\tvar title = tiddlerFields.title;\n\t\tif(title) {\n\t\t\tincomingTiddlers.push(title);\n\t\t\timportData.tiddlers[title] = tiddlerFields;\n\t\t}\n\t});\n\t// Give the active upgrader modules a chance to process the incoming tiddlers\n\tvar messages = this.wiki.invokeUpgraders(incomingTiddlers,importData.tiddlers);\n\t$tw.utils.each(messages,function(message,title) {\n\t\tnewFields[\"message-\" + title] = message;\n\t});\n\t// Deselect any suppressed tiddlers\n\t$tw.utils.each(importData.tiddlers,function(tiddler,title) {\n\t\tif($tw.utils.count(tiddler) === 0) {\n\t\t\tnewFields[\"selection-\" + title] = \"unchecked\";\n\t\t}\n\t});\n\t// Save the $:/Import tiddler\n\tnewFields.text = JSON.stringify(importData,null,$tw.config.preferences.jsonSpaces);\n\tthis.wiki.addTiddler(new $tw.Tiddler(importTiddler,newFields));\n\t// Update the story and history details\n\tif(this.getVariable(\"tv-auto-open-on-import\") !== \"no\") {\n\t\tvar storyList = this.getStoryList(),\n\t\t\thistory = [];\n\t\t// Add it to the story\n\t\tif(storyList.indexOf(IMPORT_TITLE) === -1) {\n\t\t\tstoryList.unshift(IMPORT_TITLE);\n\t\t}\n\t\t// And to history\n\t\thistory.push(IMPORT_TITLE);\n\t\t// Save the updated story and history\n\t\tthis.saveStoryList(storyList);\n\t\tthis.addToHistory(history);\n\t}\n\treturn false;\n};\n\n//\nNavigatorWidget.prototype.handlePerformImportEvent = function(event) {\n\tvar self = this,\n\t\timportTiddler = this.wiki.getTiddler(event.param),\n\t\timportData = this.wiki.getTiddlerDataCached(event.param,{tiddlers: {}}),\n\t\timportReport = [];\n\t// Add the tiddlers to the store\n\timportReport.push($tw.language.getString(\"Import/Imported/Hint\") + \"\\n\");\n\t$tw.utils.each(importData.tiddlers,function(tiddlerFields) {\n\t\tvar title = tiddlerFields.title;\n\t\tif(title && importTiddler && importTiddler.fields[\"selection-\" + title] !== \"unchecked\") {\n\t\t\tvar tiddler = new $tw.Tiddler(tiddlerFields);\n\t\t\ttiddler = $tw.hooks.invokeHook(\"th-importing-tiddler\",tiddler);\n\t\t\tself.wiki.addTiddler(tiddler);\n\t\t\timportReport.push(\"# [[\" + tiddlerFields.title + \"]]\");\n\t\t}\n\t});\n\t// Replace the $:/Import tiddler with an import report\n\tthis.wiki.addTiddler(new $tw.Tiddler({\n\t\ttitle: event.param,\n\t\ttext: importReport.join(\"\\n\"),\n\t\t\"status\": \"complete\"\n\t}));\n\t// Navigate to the $:/Import tiddler\n\tthis.addToHistory([event.param]);\n\t// Trigger an autosave\n\t$tw.rootWidget.dispatchEvent({type: \"tm-auto-save-wiki\"});\n};\n\nNavigatorWidget.prototype.handleFoldTiddlerEvent = function(event) {\n\tvar paramObject = event.paramObject || {};\n\tif(paramObject.foldedState) {\n\t\tvar foldedState = this.wiki.getTiddlerText(paramObject.foldedState,\"show\") === \"show\" ? \"hide\" : \"show\";\n\t\tthis.wiki.setText(paramObject.foldedState,\"text\",null,foldedState);\n\t}\n};\n\nNavigatorWidget.prototype.handleFoldOtherTiddlersEvent = function(event) {\n\tvar self = this,\n\t\tparamObject = event.paramObject || {},\n\t\tprefix = paramObject.foldedStatePrefix;\n\t$tw.utils.each(this.getStoryList(),function(title) {\n\t\tself.wiki.setText(prefix + title,\"text\",null,event.param === title ? \"show\" : \"hide\");\n\t});\n};\n\nNavigatorWidget.prototype.handleFoldAllTiddlersEvent = function(event) {\n\tvar self = this,\n\t\tparamObject = event.paramObject || {},\n\t\tprefix = paramObject.foldedStatePrefix;\n\t$tw.utils.each(this.getStoryList(),function(title) {\n\t\tself.wiki.setText(prefix + title,\"text\",null,\"hide\");\n\t});\n};\n\nNavigatorWidget.prototype.handleUnfoldAllTiddlersEvent = function(event) {\n\tvar self = this,\n\t\tparamObject = event.paramObject || {},\n\t\tprefix = paramObject.foldedStatePrefix;\n\t$tw.utils.each(this.getStoryList(),function(title) {\n\t\tself.wiki.setText(prefix + title,\"text\",null,\"show\");\n\t});\n};\n\nNavigatorWidget.prototype.handleRenameTiddlerEvent = function(event) {\n\tevent = $tw.hooks.invokeHook(\"th-renaming-tiddler\", event);\n\tvar paramObject = event.paramObject || {},\n\t\tfrom = paramObject.from || event.tiddlerTitle,\n\t\tto = paramObject.to;\n\t$tw.wiki.renameTiddler(from,to);\n};\n\nexports.navigator = NavigatorWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/password.js": {
"title": "$:/core/modules/widgets/password.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/password.js\ntype: application/javascript\nmodule-type: widget\n\nPassword widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar PasswordWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nPasswordWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nPasswordWidget.prototype.render = function(parent,nextSibling) {\n\t// Save the parent dom node\n\tthis.parentDomNode = parent;\n\t// Compute our attributes\n\tthis.computeAttributes();\n\t// Execute our logic\n\tthis.execute();\n\t// Get the current password\n\tvar password = $tw.browser ? $tw.utils.getPassword(this.passwordName) || \"\" : \"\";\n\t// Create our element\n\tvar domNode = this.document.createElement(\"input\");\n\tdomNode.setAttribute(\"type\",\"password\");\n\tdomNode.setAttribute(\"value\",password);\n\t// Add a click event handler\n\t$tw.utils.addEventListeners(domNode,[\n\t\t{name: \"change\", handlerObject: this, handlerMethod: \"handleChangeEvent\"}\n\t]);\n\t// Insert the label into the DOM and render any children\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.renderChildren(domNode,null);\n\tthis.domNodes.push(domNode);\n};\n\nPasswordWidget.prototype.handleChangeEvent = function(event) {\n\tvar password = this.domNodes[0].value;\n\treturn $tw.utils.savePassword(this.passwordName,password);\n};\n\n/*\nCompute the internal state of the widget\n*/\nPasswordWidget.prototype.execute = function() {\n\t// Get the parameters from the attributes\n\tthis.passwordName = this.getAttribute(\"name\",\"\");\n\t// Make the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nPasswordWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.name) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\n\t}\n};\n\nexports.password = PasswordWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/qualify.js": {
"title": "$:/core/modules/widgets/qualify.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/qualify.js\ntype: application/javascript\nmodule-type: widget\n\nQualify text to a variable \n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar QualifyWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nQualifyWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nQualifyWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nQualifyWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.qualifyName = this.getAttribute(\"name\");\n\tthis.qualifyTitle = this.getAttribute(\"title\");\n\t// Set context variable\n\tif(this.qualifyName) {\n\t\tthis.setVariable(this.qualifyName,this.qualifyTitle + \"-\" + this.getStateQualifier());\n\t}\n\t// Construct the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nQualifyWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.name || changedAttributes.title) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\n\t}\n};\n\nexports.qualify = QualifyWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/radio.js": {
"title": "$:/core/modules/widgets/radio.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/radio.js\ntype: application/javascript\nmodule-type: widget\n\nSet a field or index at a given tiddler via radio buttons\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar RadioWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nRadioWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nRadioWidget.prototype.render = function(parent,nextSibling) {\n\t// Save the parent dom node\n\tthis.parentDomNode = parent;\n\t// Compute our attributes\n\tthis.computeAttributes();\n\t// Execute our logic\n\tthis.execute();\n\tvar isChecked = this.getValue() === this.radioValue;\n\t// Create our elements\n\tthis.labelDomNode = this.document.createElement(\"label\");\n\tthis.labelDomNode.setAttribute(\"class\",\n \t\t\"tc-radio \" + this.radioClass + (isChecked ? \" tc-radio-selected\" : \"\")\n \t);\n\tthis.inputDomNode = this.document.createElement(\"input\");\n\tthis.inputDomNode.setAttribute(\"type\",\"radio\");\n\tif(isChecked) {\n\t\tthis.inputDomNode.setAttribute(\"checked\",\"true\");\n\t}\n\tthis.labelDomNode.appendChild(this.inputDomNode);\n\tthis.spanDomNode = this.document.createElement(\"span\");\n\tthis.labelDomNode.appendChild(this.spanDomNode);\n\t// Add a click event handler\n\t$tw.utils.addEventListeners(this.inputDomNode,[\n\t\t{name: \"change\", handlerObject: this, handlerMethod: \"handleChangeEvent\"}\n\t]);\n\t// Insert the label into the DOM and render any children\n\tparent.insertBefore(this.labelDomNode,nextSibling);\n\tthis.renderChildren(this.spanDomNode,null);\n\tthis.domNodes.push(this.labelDomNode);\n};\n\nRadioWidget.prototype.getValue = function() {\n\tvar value,\n\t\ttiddler = this.wiki.getTiddler(this.radioTitle);\n\tif (this.radioIndex) {\n\t\tvalue = this.wiki.extractTiddlerDataItem(this.radioTitle,this.radioIndex);\n\t} else {\n\t\tvalue = tiddler && tiddler.getFieldString(this.radioField);\n\t}\n\treturn value;\n};\n\nRadioWidget.prototype.setValue = function() {\n\tif(this.radioIndex) {\n\t\tthis.wiki.setText(this.radioTitle,\"\",this.radioIndex,this.radioValue);\n\t} else {\n\t\tvar tiddler = this.wiki.getTiddler(this.radioTitle),\n\t\t\taddition = {};\n\t\taddition[this.radioField] = this.radioValue;\n\t\tthis.wiki.addTiddler(new $tw.Tiddler(this.wiki.getCreationFields(),{title: this.radioTitle},tiddler,addition,this.wiki.getModificationFields()));\n\t}\n};\n\nRadioWidget.prototype.handleChangeEvent = function(event) {\n\tif(this.inputDomNode.checked) {\n\t\tthis.setValue();\n\t}\n};\n\n/*\nCompute the internal state of the widget\n*/\nRadioWidget.prototype.execute = function() {\n\t// Get the parameters from the attributes\n\tthis.radioTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\tthis.radioField = this.getAttribute(\"field\",\"text\");\n\tthis.radioIndex = this.getAttribute(\"index\");\n\tthis.radioValue = this.getAttribute(\"value\");\n\tthis.radioClass = this.getAttribute(\"class\",\"\");\n\t// Make the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nRadioWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes.value || changedAttributes[\"class\"]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\tvar refreshed = false;\n\t\tif(changedTiddlers[this.radioTitle]) {\n\t\t\tthis.inputDomNode.checked = this.getValue() === this.radioValue;\n\t\t\trefreshed = true;\n\t\t}\n\t\treturn this.refreshChildren(changedTiddlers) || refreshed;\n\t}\n};\n\nexports.radio = RadioWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/range.js": {
"title": "$:/core/modules/widgets/range.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/range.js\ntype: application/javascript\nmodule-type: widget\n\nRange widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar RangeWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nRangeWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nRangeWidget.prototype.render = function(parent,nextSibling) {\n\t// Save the parent dom node\n\tthis.parentDomNode = parent;\n\t// Compute our attributes\n\tthis.computeAttributes();\n\t// Execute our logic\n\tthis.execute();\n\t// Create our elements\n\tthis.inputDomNode = this.document.createElement(\"input\");\n\tthis.inputDomNode.setAttribute(\"type\",\"range\");\n\tthis.inputDomNode.setAttribute(\"class\",this.elementClass);\n\tif(this.minValue){\n\t\tthis.inputDomNode.setAttribute(\"min\", this.minValue);\n\t}\n\tif(this.maxValue){\n\t\tthis.inputDomNode.setAttribute(\"max\", this.maxValue);\n\t}\n\tif(this.increment){\n\t\tthis.inputDomNode.setAttribute(\"step\", this.increment);\n\t}\n\tthis.inputDomNode.value = this.getValue();\n\n\n\t// Add a click event handler\n\t$tw.utils.addEventListeners(this.inputDomNode,[\n\t\t{name: \"input\", handlerObject: this, handlerMethod: \"handleChangeEvent\"}\n\t]);\n\t// Insert the label into the DOM and render any children\n\tparent.insertBefore(this.inputDomNode,nextSibling);\n\tthis.domNodes.push(this.inputDomNode);\n};\n\nRangeWidget.prototype.getValue = function() {\n\tvar tiddler = this.wiki.getTiddler(this.tiddlerTitle),\n\t\tvalue = this.defaultValue;\n\tif(tiddler) {\n\t\tif($tw.utils.hop(tiddler.fields,this.tiddlerField)) {\n\t\t\tvalue = tiddler.fields[this.tiddlerField] || \"\";\n\t\t} else {\n\t\t\tvalue = this.defaultValue || \"\";\n\t\t}\n\t}\n\treturn value;\n};\n\nRangeWidget.prototype.handleChangeEvent = function(event) {\n\tthis.wiki.setText(this.tiddlerTitle ,this.tiddlerField, null,this.inputDomNode.value);\n};\n\n/*\nCompute the internal state of the widget\n*/\nRangeWidget.prototype.execute = function() {\n\t// Get the parameters from the attributes\n\tthis.tiddlerTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\tthis.tiddlerField = this.getAttribute(\"field\");\n\tthis.minValue = this.getAttribute(\"min\");\n\tthis.maxValue = this.getAttribute(\"max\");\n\tthis.increment = this.getAttribute(\"increment\");\n\tthis.defaultValue = this.getAttribute(\"default\");\n\tthis.elementClass = this.getAttribute(\"class\",\"\");\n\t// Make the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nRangeWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.tiddler || changedAttributes.field || changedAttributes['min'] || changedAttributes['max'] || changedAttributes['increment'] || changedAttributes[\"default\"] || changedAttributes[\"class\"]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\tvar refreshed = false;\n\t\tif(changedTiddlers[this.tiddlerTitle]) {\n\t\t\tthis.inputDomNode.checked = this.getValue();\n\t\t\trefreshed = true;\n\t\t}\n\t\treturn this.refreshChildren(changedTiddlers) || refreshed;\n\t}\n};\n\nexports.range = RangeWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/raw.js": {
"title": "$:/core/modules/widgets/raw.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/raw.js\ntype: application/javascript\nmodule-type: widget\n\nRaw widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar RawWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nRawWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nRawWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.execute();\n\tvar div = this.document.createElement(\"div\");\n\tdiv.innerHTML=this.parseTreeNode.html;\n\tparent.insertBefore(div,nextSibling);\n\tthis.domNodes.push(div);\t\n};\n\n/*\nCompute the internal state of the widget\n*/\nRawWidget.prototype.execute = function() {\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nRawWidget.prototype.refresh = function(changedTiddlers) {\n\treturn false;\n};\n\nexports.raw = RawWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/reveal.js": {
"title": "$:/core/modules/widgets/reveal.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/reveal.js\ntype: application/javascript\nmodule-type: widget\n\nReveal widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar RevealWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nRevealWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nRevealWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tvar tag = this.parseTreeNode.isBlock ? \"div\" : \"span\";\n\tif(this.revealTag && $tw.config.htmlUnsafeElements.indexOf(this.revealTag) === -1) {\n\t\ttag = this.revealTag;\n\t}\n\tvar domNode = this.document.createElement(tag);\n\tvar classes = this[\"class\"].split(\" \") || [];\n\tclasses.push(\"tc-reveal\");\n\tdomNode.className = classes.join(\" \");\n\tif(this.style) {\n\t\tdomNode.setAttribute(\"style\",this.style);\n\t}\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.renderChildren(domNode,null);\n\tif(!domNode.isTiddlyWikiFakeDom && this.type === \"popup\" && this.isOpen) {\n\t\tthis.positionPopup(domNode);\n\t\t$tw.utils.addClass(domNode,\"tc-popup\"); // Make sure that clicks don't dismiss popups within the revealed content\n\t}\n\tif(!this.isOpen) {\n\t\tdomNode.setAttribute(\"hidden\",\"true\");\n\t}\n\tthis.domNodes.push(domNode);\n};\n\nRevealWidget.prototype.positionPopup = function(domNode) {\n\tdomNode.style.position = \"absolute\";\n\tdomNode.style.zIndex = \"1000\";\n\tswitch(this.position) {\n\t\tcase \"left\":\n\t\t\tdomNode.style.left = Math.max(0, this.popup.left - domNode.offsetWidth) + \"px\";\n\t\t\tdomNode.style.top = this.popup.top + \"px\";\n\t\t\tbreak;\n\t\tcase \"above\":\n\t\t\tdomNode.style.left = this.popup.left + \"px\";\n\t\t\tdomNode.style.top = Math.max(0, this.popup.top - domNode.offsetHeight) + \"px\";\n\t\t\tbreak;\n\t\tcase \"aboveright\":\n\t\t\tdomNode.style.left = (this.popup.left + this.popup.width) + \"px\";\n\t\t\tdomNode.style.top = Math.max(0, this.popup.top + this.popup.height - domNode.offsetHeight) + \"px\";\n\t\t\tbreak;\n\t\tcase \"right\":\n\t\t\tdomNode.style.left = (this.popup.left + this.popup.width) + \"px\";\n\t\t\tdomNode.style.top = this.popup.top + \"px\";\n\t\t\tbreak;\n\t\tcase \"belowleft\":\n\t\t\tdomNode.style.left = Math.max(0, this.popup.left + this.popup.width - domNode.offsetWidth) + \"px\";\n\t\t\tdomNode.style.top = (this.popup.top + this.popup.height) + \"px\";\n\t\t\tbreak;\n\t\tdefault: // Below\n\t\t\tdomNode.style.left = this.popup.left + \"px\";\n\t\t\tdomNode.style.top = (this.popup.top + this.popup.height) + \"px\";\n\t\t\tbreak;\n\t}\n};\n\n/*\nCompute the internal state of the widget\n*/\nRevealWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.state = this.getAttribute(\"state\");\n\tthis.revealTag = this.getAttribute(\"tag\");\n\tthis.type = this.getAttribute(\"type\");\n\tthis.text = this.getAttribute(\"text\");\n\tthis.position = this.getAttribute(\"position\");\n\tthis[\"class\"] = this.getAttribute(\"class\",\"\");\n\tthis.style = this.getAttribute(\"style\",\"\");\n\tthis[\"default\"] = this.getAttribute(\"default\",\"\");\n\tthis.animate = this.getAttribute(\"animate\",\"no\");\n\tthis.retain = this.getAttribute(\"retain\",\"no\");\n\tthis.openAnimation = this.animate === \"no\" ? undefined : \"open\";\n\tthis.closeAnimation = this.animate === \"no\" ? undefined : \"close\";\n\t// Compute the title of the state tiddler and read it\n\tthis.stateTiddlerTitle = this.state;\n\tthis.stateTitle = this.getAttribute(\"stateTitle\");\n\tthis.stateField = this.getAttribute(\"stateField\");\n\tthis.stateIndex = this.getAttribute(\"stateIndex\");\n\tthis.readState();\n\t// Construct the child widgets\n\tvar childNodes = this.isOpen ? this.parseTreeNode.children : [];\n\tthis.hasChildNodes = this.isOpen;\n\tthis.makeChildWidgets(childNodes);\n};\n\n/*\nRead the state tiddler\n*/\nRevealWidget.prototype.readState = function() {\n\t// Read the information from the state tiddler\n\tvar state = this.stateTitle ? (this.stateField ? this.wiki.getTiddler(this.stateTitle).getFieldString(this.stateField) :\n\t\t(this.stateIndex ? this.wiki.extractTiddlerDataItem(this.stateTitle,this.stateIndex) :\n\t\t\tthis.wiki.getTiddlerText(this.stateTitle))) || this[\"default\"] || this.getVariable(\"currentTiddler\") :\n\t\t(this.stateTiddlerTitle ? this.wiki.getTextReference(this.state,this[\"default\"],this.getVariable(\"currentTiddler\")) : this[\"default\"]);\n\tif(state === null) {\n\t\tstate = this[\"default\"];\n\t}\n\tswitch(this.type) {\n\t\tcase \"popup\":\n\t\t\tthis.readPopupState(state);\n\t\t\tbreak;\n\t\tcase \"match\":\n\t\t\tthis.isOpen = !!(this.compareStateText(state) == 0);\n\t\t\tbreak;\n\t\tcase \"nomatch\":\n\t\t\tthis.isOpen = !(this.compareStateText(state) == 0);\n\t\t\tbreak;\n\t\tcase \"lt\":\n\t\t\tthis.isOpen = !!(this.compareStateText(state) < 0);\n\t\t\tbreak;\n\t\tcase \"gt\":\n\t\t\tthis.isOpen = !!(this.compareStateText(state) > 0);\n\t\t\tbreak;\n\t\tcase \"lteq\":\n\t\t\tthis.isOpen = !(this.compareStateText(state) > 0);\n\t\t\tbreak;\n\t\tcase \"gteq\":\n\t\t\tthis.isOpen = !(this.compareStateText(state) < 0);\n\t\t\tbreak;\n\t}\n};\n\nRevealWidget.prototype.compareStateText = function(state) {\n\treturn state.localeCompare(this.text,undefined,{numeric: true,sensitivity: \"case\"});\n};\n\nRevealWidget.prototype.readPopupState = function(state) {\n\tvar popupLocationRegExp = /^\\((-?[0-9\\.E]+),(-?[0-9\\.E]+),(-?[0-9\\.E]+),(-?[0-9\\.E]+)\\)$/,\n\t\tmatch = popupLocationRegExp.exec(state);\n\t// Check if the state matches the location regexp\n\tif(match) {\n\t\t// If so, we're open\n\t\tthis.isOpen = true;\n\t\t// Get the location\n\t\tthis.popup = {\n\t\t\tleft: parseFloat(match[1]),\n\t\t\ttop: parseFloat(match[2]),\n\t\t\twidth: parseFloat(match[3]),\n\t\t\theight: parseFloat(match[4])\n\t\t};\n\t} else {\n\t\t// If not, we're closed\n\t\tthis.isOpen = false;\n\t}\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nRevealWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.state || changedAttributes.type || changedAttributes.text || changedAttributes.position || changedAttributes[\"default\"] || changedAttributes.animate || changedAttributes.stateTitle || changedAttributes.stateField || changedAttributes.stateIndex) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\tvar currentlyOpen = this.isOpen;\n\t\tthis.readState();\n\t\tif(this.isOpen !== currentlyOpen || (this.stateTiddlerTitle && changedTiddlers[this.stateTiddlerTitle])) {\n\t\t\tif(this.retain === \"yes\") {\n\t\t\t\tthis.updateState();\n\t\t\t} else {\n\t\t\t\tthis.refreshSelf();\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn this.refreshChildren(changedTiddlers);\n\t}\n};\n\n/*\nCalled by refresh() to dynamically show or hide the content\n*/\nRevealWidget.prototype.updateState = function() {\n\tvar self = this;\n\t// Read the current state\n\tthis.readState();\n\t// Construct the child nodes if needed\n\tvar domNode = this.domNodes[0];\n\tif(this.isOpen && !this.hasChildNodes) {\n\t\tthis.hasChildNodes = true;\n\t\tthis.makeChildWidgets(this.parseTreeNode.children);\n\t\tthis.renderChildren(domNode,null);\n\t}\n\t// Animate our DOM node\n\tif(!domNode.isTiddlyWikiFakeDom && this.type === \"popup\" && this.isOpen) {\n\t\tthis.positionPopup(domNode);\n\t\t$tw.utils.addClass(domNode,\"tc-popup\"); // Make sure that clicks don't dismiss popups within the revealed content\n\n\t}\n\tif(this.isOpen) {\n\t\tdomNode.removeAttribute(\"hidden\");\n $tw.anim.perform(this.openAnimation,domNode);\n\t} else {\n\t\t$tw.anim.perform(this.closeAnimation,domNode,{callback: function() {\n\t\t\t//make sure that the state hasn't changed during the close animation\n\t\t\tself.readState()\n\t\t\tif(!self.isOpen) {\n\t\t\t\tdomNode.setAttribute(\"hidden\",\"true\");\n\t\t\t}\n\t\t}});\n\t}\n};\n\nexports.reveal = RevealWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/scrollable.js": {
"title": "$:/core/modules/widgets/scrollable.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/scrollable.js\ntype: application/javascript\nmodule-type: widget\n\nScrollable widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar ScrollableWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n\tthis.scaleFactor = 1;\n\tthis.addEventListeners([\n\t\t{type: \"tm-scroll\", handler: \"handleScrollEvent\"}\n\t]);\n\tif($tw.browser) {\n\t\tthis.requestAnimationFrame = window.requestAnimationFrame ||\n\t\t\twindow.webkitRequestAnimationFrame ||\n\t\t\twindow.mozRequestAnimationFrame ||\n\t\t\tfunction(callback) {\n\t\t\t\treturn window.setTimeout(callback, 1000/60);\n\t\t\t};\n\t\tthis.cancelAnimationFrame = window.cancelAnimationFrame ||\n\t\t\twindow.webkitCancelAnimationFrame ||\n\t\t\twindow.webkitCancelRequestAnimationFrame ||\n\t\t\twindow.mozCancelAnimationFrame ||\n\t\t\twindow.mozCancelRequestAnimationFrame ||\n\t\t\tfunction(id) {\n\t\t\t\twindow.clearTimeout(id);\n\t\t\t};\n\t}\n};\n\n/*\nInherit from the base widget class\n*/\nScrollableWidget.prototype = new Widget();\n\nScrollableWidget.prototype.cancelScroll = function() {\n\tif(this.idRequestFrame) {\n\t\tthis.cancelAnimationFrame.call(window,this.idRequestFrame);\n\t\tthis.idRequestFrame = null;\n\t}\n};\n\n/*\nHandle a scroll event\n*/\nScrollableWidget.prototype.handleScrollEvent = function(event) {\n\t// Pass the scroll event through if our offsetsize is larger than our scrollsize\n\tif(this.outerDomNode.scrollWidth <= this.outerDomNode.offsetWidth && this.outerDomNode.scrollHeight <= this.outerDomNode.offsetHeight && this.fallthrough === \"yes\") {\n\t\treturn true;\n\t}\n\tthis.scrollIntoView(event.target);\n\treturn false; // Handled event\n};\n\n/*\nScroll an element into view\n*/\nScrollableWidget.prototype.scrollIntoView = function(element) {\n\tvar duration = $tw.utils.getAnimationDuration();\n\tthis.cancelScroll();\n\tthis.startTime = Date.now();\n\tvar scrollPosition = {\n\t\tx: this.outerDomNode.scrollLeft,\n\t\ty: this.outerDomNode.scrollTop\n\t};\n\t// Get the client bounds of the element and adjust by the scroll position\n\tvar scrollableBounds = this.outerDomNode.getBoundingClientRect(),\n\t\tclientTargetBounds = element.getBoundingClientRect(),\n\t\tbounds = {\n\t\t\tleft: clientTargetBounds.left + scrollPosition.x - scrollableBounds.left,\n\t\t\ttop: clientTargetBounds.top + scrollPosition.y - scrollableBounds.top,\n\t\t\twidth: clientTargetBounds.width,\n\t\t\theight: clientTargetBounds.height\n\t\t};\n\t// We'll consider the horizontal and vertical scroll directions separately via this function\n\tvar getEndPos = function(targetPos,targetSize,currentPos,currentSize) {\n\t\t\t// If the target is already visible then stay where we are\n\t\t\tif(targetPos >= currentPos && (targetPos + targetSize) <= (currentPos + currentSize)) {\n\t\t\t\treturn currentPos;\n\t\t\t// If the target is above/left of the current view, then scroll to its top/left\n\t\t\t} else if(targetPos <= currentPos) {\n\t\t\t\treturn targetPos;\n\t\t\t// If the target is smaller than the window and the scroll position is too far up, then scroll till the target is at the bottom of the window\n\t\t\t} else if(targetSize < currentSize && currentPos < (targetPos + targetSize - currentSize)) {\n\t\t\t\treturn targetPos + targetSize - currentSize;\n\t\t\t// If the target is big, then just scroll to the top\n\t\t\t} else if(currentPos < targetPos) {\n\t\t\t\treturn targetPos;\n\t\t\t// Otherwise, stay where we are\n\t\t\t} else {\n\t\t\t\treturn currentPos;\n\t\t\t}\n\t\t},\n\t\tendX = getEndPos(bounds.left,bounds.width,scrollPosition.x,this.outerDomNode.offsetWidth),\n\t\tendY = getEndPos(bounds.top,bounds.height,scrollPosition.y,this.outerDomNode.offsetHeight);\n\t// Only scroll if necessary\n\tif(endX !== scrollPosition.x || endY !== scrollPosition.y) {\n\t\tvar self = this,\n\t\t\tdrawFrame;\n\t\tdrawFrame = function () {\n\t\t\tvar t;\n\t\t\tif(duration <= 0) {\n\t\t\t\tt = 1;\n\t\t\t} else {\n\t\t\t\tt = ((Date.now()) - self.startTime) / duration;\t\n\t\t\t}\n\t\t\tif(t >= 1) {\n\t\t\t\tself.cancelScroll();\n\t\t\t\tt = 1;\n\t\t\t}\n\t\t\tt = $tw.utils.slowInSlowOut(t);\n\t\t\tself.outerDomNode.scrollLeft = scrollPosition.x + (endX - scrollPosition.x) * t;\n\t\t\tself.outerDomNode.scrollTop = scrollPosition.y + (endY - scrollPosition.y) * t;\n\t\t\tif(t < 1) {\n\t\t\t\tself.idRequestFrame = self.requestAnimationFrame.call(window,drawFrame);\n\t\t\t}\n\t\t};\n\t\tdrawFrame();\n\t}\n};\n\n/*\nRender this widget into the DOM\n*/\nScrollableWidget.prototype.render = function(parent,nextSibling) {\n\tvar self = this;\n\t// Remember parent\n\tthis.parentDomNode = parent;\n\t// Compute attributes and execute state\n\tthis.computeAttributes();\n\tthis.execute();\n\t// Create elements\n\tthis.outerDomNode = this.document.createElement(\"div\");\n\t$tw.utils.setStyle(this.outerDomNode,[\n\t\t{overflowY: \"auto\"},\n\t\t{overflowX: \"auto\"},\n\t\t{webkitOverflowScrolling: \"touch\"}\n\t]);\n\tthis.innerDomNode = this.document.createElement(\"div\");\n\tthis.outerDomNode.appendChild(this.innerDomNode);\n\t// Assign classes\n\tthis.outerDomNode.className = this[\"class\"] || \"\";\n\t// Insert element\n\tparent.insertBefore(this.outerDomNode,nextSibling);\n\tthis.renderChildren(this.innerDomNode,null);\n\tthis.domNodes.push(this.outerDomNode);\n};\n\n/*\nCompute the internal state of the widget\n*/\nScrollableWidget.prototype.execute = function() {\n\t// Get attributes\n\tthis.fallthrough = this.getAttribute(\"fallthrough\",\"yes\");\n\tthis[\"class\"] = this.getAttribute(\"class\");\n\t// Make child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nScrollableWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes[\"class\"]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\nexports.scrollable = ScrollableWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/select.js": {
"title": "$:/core/modules/widgets/select.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/select.js\ntype: application/javascript\nmodule-type: widget\n\nSelect widget:\n\n```\n<$select tiddler=\"MyTiddler\" field=\"text\">\n<$list filter=\"[tag[chapter]]\">\n<option value=<<currentTiddler>>>\n<$view field=\"description\"/>\n</option>\n</$list>\n</$select>\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar SelectWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nSelectWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nSelectWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n\tthis.setSelectValue();\n\t$tw.utils.addEventListeners(this.getSelectDomNode(),[\n\t\t{name: \"change\", handlerObject: this, handlerMethod: \"handleChangeEvent\"}\n\t]);\n};\n\n/*\nHandle a change event\n*/\nSelectWidget.prototype.handleChangeEvent = function(event) {\n\t// Get the new value and assign it to the tiddler\n\tif(this.selectMultiple == false) {\n\t\tvar value = this.getSelectDomNode().value;\n\t} else {\n\t\tvar value = this.getSelectValues()\n\t\t\t\tvalue = $tw.utils.stringifyList(value);\n\t}\n\tthis.wiki.setText(this.selectTitle,this.selectField,this.selectIndex,value);\n\t// Trigger actions\n\tif(this.selectActions) {\n\t\tthis.invokeActionString(this.selectActions,this,event);\n\t}\n};\n\n/*\nIf necessary, set the value of the select element to the current value\n*/\nSelectWidget.prototype.setSelectValue = function() {\n\tvar value = this.selectDefault;\n\t// Get the value\n\tif(this.selectIndex) {\n\t\tvalue = this.wiki.extractTiddlerDataItem(this.selectTitle,this.selectIndex,value);\n\t} else {\n\t\tvar tiddler = this.wiki.getTiddler(this.selectTitle);\n\t\tif(tiddler) {\n\t\t\tif(this.selectField === \"text\") {\n\t\t\t\t// Calling getTiddlerText() triggers lazy loading of skinny tiddlers\n\t\t\t\tvalue = this.wiki.getTiddlerText(this.selectTitle);\n\t\t\t} else {\n\t\t\t\tif($tw.utils.hop(tiddler.fields,this.selectField)) {\n\t\t\t\t\tvalue = tiddler.getFieldString(this.selectField);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tif(this.selectField === \"title\") {\n\t\t\t\tvalue = this.selectTitle;\n\t\t\t}\n\t\t}\n\t}\n\t// Assign it to the select element if it's different than the current value\n\tif (this.selectMultiple) {\n\t\tvalue = value === undefined ? \"\" : value;\n\t\tvar select = this.getSelectDomNode();\n\t\tvar values = Array.isArray(value) ? value : $tw.utils.parseStringArray(value);\n\t\tfor(var i=0; i < select.children.length; i++){\n\t\t\tif(values.indexOf(select.children[i].value) != -1) {\n\t\t\t\tselect.children[i].selected = true;\n\t\t\t}\n\t\t}\n\t\t\n\t} else {\n\t\tvar domNode = this.getSelectDomNode();\n\t\tif(domNode.value !== value) {\n\t\t\tdomNode.value = value;\n\t\t}\n\t}\n};\n\n/*\nGet the DOM node of the select element\n*/\nSelectWidget.prototype.getSelectDomNode = function() {\n\treturn this.children[0].domNodes[0];\n};\n\n// Return an array of the selected opion values\n// select is an HTML select element\nSelectWidget.prototype.getSelectValues = function() {\n\tvar select, result, options, opt;\n\tselect = this.getSelectDomNode();\n\tresult = [];\n\toptions = select && select.options;\n\tfor (var i=0; i<options.length; i++) {\n\t\topt = options[i];\n\t\tif (opt.selected) {\n\t\t\tresult.push(opt.value || opt.text);\n\t\t}\n\t}\n\treturn result;\n}\n\n/*\nCompute the internal state of the widget\n*/\nSelectWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.selectActions = this.getAttribute(\"actions\");\n\tthis.selectTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\tthis.selectField = this.getAttribute(\"field\",\"text\");\n\tthis.selectIndex = this.getAttribute(\"index\");\n\tthis.selectClass = this.getAttribute(\"class\");\n\tthis.selectDefault = this.getAttribute(\"default\");\n\tthis.selectMultiple = this.getAttribute(\"multiple\", false);\n\tthis.selectSize = this.getAttribute(\"size\");\n\t// Make the child widgets\n\tvar selectNode = {\n\t\ttype: \"element\",\n\t\ttag: \"select\",\n\t\tchildren: this.parseTreeNode.children\n\t};\n\tif(this.selectClass) {\n\t\t$tw.utils.addAttributeToParseTreeNode(selectNode,\"class\",this.selectClass);\n\t}\n\tif(this.selectMultiple) {\n\t\t$tw.utils.addAttributeToParseTreeNode(selectNode,\"multiple\",\"multiple\");\n\t}\n\tif(this.selectSize) {\n\t\t$tw.utils.addAttributeToParseTreeNode(selectNode,\"size\",this.selectSize);\n\t}\n\tthis.makeChildWidgets([selectNode]);\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nSelectWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\t// If we're using a different tiddler/field/index then completely refresh ourselves\n\tif(changedAttributes.selectTitle || changedAttributes.selectField || changedAttributes.selectIndex) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t// If the target tiddler value has changed, just update setting and refresh the children\n\t} else {\n\t\tvar childrenRefreshed = this.refreshChildren(changedTiddlers);\n\t\tif(changedTiddlers[this.selectTitle] || childrenRefreshed) {\n\t\t\tthis.setSelectValue();\n\t\t} \n\t\treturn childrenRefreshed;\n\t}\n};\n\nexports.select = SelectWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/set.js": {
"title": "$:/core/modules/widgets/set.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/set.js\ntype: application/javascript\nmodule-type: widget\n\nSet variable widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar SetWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nSetWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nSetWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nSetWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.setName = this.getAttribute(\"name\",\"currentTiddler\");\n\tthis.setFilter = this.getAttribute(\"filter\");\n\tthis.setSelect = this.getAttribute(\"select\");\n\tthis.setTiddler = this.getAttribute(\"tiddler\");\n\tthis.setSubTiddler = this.getAttribute(\"subtiddler\");\n\tthis.setField = this.getAttribute(\"field\");\n\tthis.setIndex = this.getAttribute(\"index\");\n\tthis.setValue = this.getAttribute(\"value\");\n\tthis.setEmptyValue = this.getAttribute(\"emptyValue\");\n\t// Set context variable\n\tthis.setVariable(this.setName,this.getValue(),this.parseTreeNode.params,!!this.parseTreeNode.isMacroDefinition);\n\t// Construct the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nGet the value to be assigned\n*/\nSetWidget.prototype.getValue = function() {\n\tvar value = this.setValue;\n\tif(this.setTiddler) {\n\t\tvar tiddler;\n\t\tif(this.setSubTiddler) {\n\t\t\ttiddler = this.wiki.getSubTiddler(this.setTiddler,this.setSubTiddler);\n\t\t} else {\n\t\t\ttiddler = this.wiki.getTiddler(this.setTiddler);\t\t\t\n\t\t}\n\t\tif(!tiddler) {\n\t\t\tvalue = this.setEmptyValue;\n\t\t} else if(this.setField) {\n\t\t\tvalue = tiddler.getFieldString(this.setField) || this.setEmptyValue;\n\t\t} else if(this.setIndex) {\n\t\t\tvalue = this.wiki.extractTiddlerDataItem(this.setTiddler,this.setIndex,this.setEmptyValue);\n\t\t} else {\n\t\t\tvalue = tiddler.fields.text || this.setEmptyValue ;\n\t\t}\n\t} else if(this.setFilter) {\n\t\tvar results = this.wiki.filterTiddlers(this.setFilter,this);\n\t\tif(this.setValue == null) {\n\t\t\tvar select;\n\t\t\tif(this.setSelect) {\n\t\t\t\tselect = parseInt(this.setSelect,10);\n\t\t\t}\n\t\t\tif(select !== undefined) {\n\t\t\t\tvalue = results[select] || \"\";\n\t\t\t} else {\n\t\t\t\tvalue = $tw.utils.stringifyList(results);\t\t\t\n\t\t\t}\n\t\t}\n\t\tif(results.length === 0 && this.setEmptyValue !== undefined) {\n\t\t\tvalue = this.setEmptyValue;\n\t\t}\n\t} else if(!value && this.setEmptyValue) {\n\t\tvalue = this.setEmptyValue;\n\t}\n\treturn value || \"\";\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nSetWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.name || changedAttributes.filter || changedAttributes.select || changedAttributes.tiddler || (this.setTiddler && changedTiddlers[this.setTiddler]) || changedAttributes.field || changedAttributes.index || changedAttributes.value || changedAttributes.emptyValue ||\n\t (this.setFilter && this.getValue() != this.variables[this.setName].value)) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\n\t}\n};\n\nexports.setvariable = SetWidget;\nexports.set = SetWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/text.js": {
"title": "$:/core/modules/widgets/text.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/text.js\ntype: application/javascript\nmodule-type: widget\n\nText node widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar TextNodeWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nTextNodeWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nTextNodeWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tvar text = this.getAttribute(\"text\",this.parseTreeNode.text || \"\");\n\ttext = text.replace(/\\r/mg,\"\");\n\tvar textNode = this.document.createTextNode(text);\n\tparent.insertBefore(textNode,nextSibling);\n\tthis.domNodes.push(textNode);\n};\n\n/*\nCompute the internal state of the widget\n*/\nTextNodeWidget.prototype.execute = function() {\n\t// Nothing to do for a text node\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nTextNodeWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.text) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn false;\t\n\t}\n};\n\nexports.text = TextNodeWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/tiddler.js": {
"title": "$:/core/modules/widgets/tiddler.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/tiddler.js\ntype: application/javascript\nmodule-type: widget\n\nTiddler widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar TiddlerWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nTiddlerWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nTiddlerWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nTiddlerWidget.prototype.execute = function() {\n\tthis.tiddlerState = this.computeTiddlerState();\n\tthis.setVariable(\"currentTiddler\",this.tiddlerState.currentTiddler);\n\tthis.setVariable(\"missingTiddlerClass\",this.tiddlerState.missingTiddlerClass);\n\tthis.setVariable(\"shadowTiddlerClass\",this.tiddlerState.shadowTiddlerClass);\n\tthis.setVariable(\"systemTiddlerClass\",this.tiddlerState.systemTiddlerClass);\n\tthis.setVariable(\"tiddlerTagClasses\",this.tiddlerState.tiddlerTagClasses);\n\t// Construct the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nCompute the tiddler state flags\n*/\nTiddlerWidget.prototype.computeTiddlerState = function() {\n\t// Get our parameters\n\tthis.tiddlerTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\t// Compute the state\n\tvar state = {\n\t\tcurrentTiddler: this.tiddlerTitle || \"\",\n\t\tmissingTiddlerClass: (this.wiki.tiddlerExists(this.tiddlerTitle) || this.wiki.isShadowTiddler(this.tiddlerTitle)) ? \"tc-tiddler-exists\" : \"tc-tiddler-missing\",\n\t\tshadowTiddlerClass: this.wiki.isShadowTiddler(this.tiddlerTitle) ? \"tc-tiddler-shadow\" : \"\",\n\t\tsystemTiddlerClass: this.wiki.isSystemTiddler(this.tiddlerTitle) ? \"tc-tiddler-system\" : \"\",\n\t\ttiddlerTagClasses: this.getTagClasses()\n\t};\n\t// Compute a simple hash to make it easier to detect changes\n\tstate.hash = state.currentTiddler + state.missingTiddlerClass + state.shadowTiddlerClass + state.systemTiddlerClass + state.tiddlerTagClasses;\n\treturn state;\n};\n\n/*\nCreate a string of CSS classes derived from the tags of the current tiddler\n*/\nTiddlerWidget.prototype.getTagClasses = function() {\n\tvar tiddler = this.wiki.getTiddler(this.tiddlerTitle);\n\tif(tiddler) {\n\t\tvar tags = [];\n\t\t$tw.utils.each(tiddler.fields.tags,function(tag) {\n\t\t\ttags.push(\"tc-tagged-\" + encodeURIComponent(tag));\n\t\t});\n\t\treturn tags.join(\" \");\n\t} else {\n\t\treturn \"\";\n\t}\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nTiddlerWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes(),\n\t\tnewTiddlerState = this.computeTiddlerState();\n\tif(changedAttributes.tiddler || newTiddlerState.hash !== this.tiddlerState.hash) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\t\t\n\t}\n};\n\nexports.tiddler = TiddlerWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/transclude.js": {
"title": "$:/core/modules/widgets/transclude.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/transclude.js\ntype: application/javascript\nmodule-type: widget\n\nTransclude widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar TranscludeWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nTranscludeWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nTranscludeWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nTranscludeWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.transcludeTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\tthis.transcludeSubTiddler = this.getAttribute(\"subtiddler\");\n\tthis.transcludeField = this.getAttribute(\"field\");\n\tthis.transcludeIndex = this.getAttribute(\"index\");\n\tthis.transcludeMode = this.getAttribute(\"mode\");\n\t// Parse the text reference\n\tvar parseAsInline = !this.parseTreeNode.isBlock;\n\tif(this.transcludeMode === \"inline\") {\n\t\tparseAsInline = true;\n\t} else if(this.transcludeMode === \"block\") {\n\t\tparseAsInline = false;\n\t}\n\tvar parser = this.wiki.parseTextReference(\n\t\t\t\t\t\tthis.transcludeTitle,\n\t\t\t\t\t\tthis.transcludeField,\n\t\t\t\t\t\tthis.transcludeIndex,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tparseAsInline: parseAsInline,\n\t\t\t\t\t\t\tsubTiddler: this.transcludeSubTiddler\n\t\t\t\t\t\t}),\n\t\tparseTreeNodes = parser ? parser.tree : this.parseTreeNode.children;\n\t// Set context variables for recursion detection\n\tvar recursionMarker = this.makeRecursionMarker();\n\tthis.setVariable(\"transclusion\",recursionMarker);\n\t// Check for recursion\n\tif(parser) {\n\t\tif(this.parentWidget && this.parentWidget.hasVariable(\"transclusion\",recursionMarker)) {\n\t\t\tparseTreeNodes = [{type: \"element\", tag: \"span\", attributes: {\n\t\t\t\t\"class\": {type: \"string\", value: \"tc-error\"}\n\t\t\t}, children: [\n\t\t\t\t{type: \"text\", text: $tw.language.getString(\"Error/RecursiveTransclusion\")}\n\t\t\t]}];\n\t\t}\n\t}\n\t// Construct the child widgets\n\tthis.makeChildWidgets(parseTreeNodes);\n};\n\n/*\nCompose a string comprising the title, field and/or index to identify this transclusion for recursion detection\n*/\nTranscludeWidget.prototype.makeRecursionMarker = function() {\n\tvar output = [];\n\toutput.push(\"{\");\n\toutput.push(this.getVariable(\"currentTiddler\",{defaultValue: \"\"}));\n\toutput.push(\"|\");\n\toutput.push(this.transcludeTitle || \"\");\n\toutput.push(\"|\");\n\toutput.push(this.transcludeField || \"\");\n\toutput.push(\"|\");\n\toutput.push(this.transcludeIndex || \"\");\n\toutput.push(\"|\");\n\toutput.push(this.transcludeSubTiddler || \"\");\n\toutput.push(\"}\");\n\treturn output.join(\"\");\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nTranscludeWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedTiddlers[this.transcludeTitle]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\t\t\n\t}\n};\n\nexports.transclude = TranscludeWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/vars.js": {
"title": "$:/core/modules/widgets/vars.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/vars.js\ntype: application/javascript\nmodule-type: widget\n\nThis widget allows multiple variables to be set in one go:\n\n```\n\\define helloworld() Hello world!\n<$vars greeting=\"Hi\" me={{!!title}} sentence=<<helloworld>>>\n <<greeting>>! I am <<me>> and I say: <<sentence>>\n</$vars>\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar VarsWidget = function(parseTreeNode,options) {\n\t// Call the constructor\n\tWidget.call(this);\n\t// Initialise\t\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nVarsWidget.prototype = Object.create(Widget.prototype);\n\n/*\nRender this widget into the DOM\n*/\nVarsWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nVarsWidget.prototype.execute = function() {\n\t// Parse variables\n\tvar self = this;\n\t$tw.utils.each(this.attributes,function(val,key) {\n\t\tif(key.charAt(0) !== \"$\") {\n\t\t\tself.setVariable(key,val);\n\t\t}\n\t});\n\t// Construct the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nRefresh the widget by ensuring our attributes are up to date\n*/\nVarsWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(Object.keys(changedAttributes).length) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\nexports[\"vars\"] = VarsWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/view.js": {
"title": "$:/core/modules/widgets/view.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/view.js\ntype: application/javascript\nmodule-type: widget\n\nView widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar ViewWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nViewWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nViewWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tif(this.text) {\n\t\tvar textNode = this.document.createTextNode(this.text);\n\t\tparent.insertBefore(textNode,nextSibling);\n\t\tthis.domNodes.push(textNode);\n\t} else {\n\t\tthis.makeChildWidgets();\n\t\tthis.renderChildren(parent,nextSibling);\n\t}\n};\n\n/*\nCompute the internal state of the widget\n*/\nViewWidget.prototype.execute = function() {\n\t// Get parameters from our attributes\n\tthis.viewTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\tthis.viewSubtiddler = this.getAttribute(\"subtiddler\");\n\tthis.viewField = this.getAttribute(\"field\",\"text\");\n\tthis.viewIndex = this.getAttribute(\"index\");\n\tthis.viewFormat = this.getAttribute(\"format\",\"text\");\n\tthis.viewTemplate = this.getAttribute(\"template\",\"\");\n\tthis.viewMode = this.getAttribute(\"mode\",\"block\");\n\tswitch(this.viewFormat) {\n\t\tcase \"htmlwikified\":\n\t\t\tthis.text = this.getValueAsHtmlWikified(this.viewMode);\n\t\t\tbreak;\n\t\tcase \"plainwikified\":\n\t\t\tthis.text = this.getValueAsPlainWikified(this.viewMode);\n\t\t\tbreak;\n\t\tcase \"htmlencodedplainwikified\":\n\t\t\tthis.text = this.getValueAsHtmlEncodedPlainWikified(this.viewMode);\n\t\t\tbreak;\n\t\tcase \"htmlencoded\":\n\t\t\tthis.text = this.getValueAsHtmlEncoded();\n\t\t\tbreak;\n\t\tcase \"urlencoded\":\n\t\t\tthis.text = this.getValueAsUrlEncoded();\n\t\t\tbreak;\n\t\tcase \"doubleurlencoded\":\n\t\t\tthis.text = this.getValueAsDoubleUrlEncoded();\n\t\t\tbreak;\n\t\tcase \"date\":\n\t\t\tthis.text = this.getValueAsDate(this.viewTemplate);\n\t\t\tbreak;\n\t\tcase \"relativedate\":\n\t\t\tthis.text = this.getValueAsRelativeDate();\n\t\t\tbreak;\n\t\tcase \"stripcomments\":\n\t\t\tthis.text = this.getValueAsStrippedComments();\n\t\t\tbreak;\n\t\tcase \"jsencoded\":\n\t\t\tthis.text = this.getValueAsJsEncoded();\n\t\t\tbreak;\n\t\tdefault: // \"text\"\n\t\t\tthis.text = this.getValueAsText();\n\t\t\tbreak;\n\t}\n};\n\n/*\nThe various formatter functions are baked into this widget for the moment. Eventually they will be replaced by macro functions\n*/\n\n/*\nRetrieve the value of the widget. Options are:\nasString: Optionally return the value as a string\n*/\nViewWidget.prototype.getValue = function(options) {\n\toptions = options || {};\n\tvar value = options.asString ? \"\" : undefined;\n\tif(this.viewIndex) {\n\t\tvalue = this.wiki.extractTiddlerDataItem(this.viewTitle,this.viewIndex);\n\t} else {\n\t\tvar tiddler;\n\t\tif(this.viewSubtiddler) {\n\t\t\ttiddler = this.wiki.getSubTiddler(this.viewTitle,this.viewSubtiddler);\t\n\t\t} else {\n\t\t\ttiddler = this.wiki.getTiddler(this.viewTitle);\n\t\t}\n\t\tif(tiddler) {\n\t\t\tif(this.viewField === \"text\" && !this.viewSubtiddler) {\n\t\t\t\t// Calling getTiddlerText() triggers lazy loading of skinny tiddlers\n\t\t\t\tvalue = this.wiki.getTiddlerText(this.viewTitle);\n\t\t\t} else {\n\t\t\t\tif($tw.utils.hop(tiddler.fields,this.viewField)) {\n\t\t\t\t\tif(options.asString) {\n\t\t\t\t\t\tvalue = tiddler.getFieldString(this.viewField);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tvalue = tiddler.fields[this.viewField];\t\t\t\t\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tif(this.viewField === \"title\") {\n\t\t\t\tvalue = this.viewTitle;\n\t\t\t}\n\t\t}\n\t}\n\treturn value;\n};\n\nViewWidget.prototype.getValueAsText = function() {\n\treturn this.getValue({asString: true});\n};\n\nViewWidget.prototype.getValueAsHtmlWikified = function(mode) {\n\treturn this.wiki.renderText(\"text/html\",\"text/vnd.tiddlywiki\",this.getValueAsText(),{\n\t\tparseAsInline: mode !== \"block\",\n\t\tparentWidget: this\n\t});\n};\n\nViewWidget.prototype.getValueAsPlainWikified = function(mode) {\n\treturn this.wiki.renderText(\"text/plain\",\"text/vnd.tiddlywiki\",this.getValueAsText(),{\n\t\tparseAsInline: mode !== \"block\",\n\t\tparentWidget: this\n\t});\n};\n\nViewWidget.prototype.getValueAsHtmlEncodedPlainWikified = function(mode) {\n\treturn $tw.utils.htmlEncode(this.wiki.renderText(\"text/plain\",\"text/vnd.tiddlywiki\",this.getValueAsText(),{\n\t\tparseAsInline: mode !== \"block\",\n\t\tparentWidget: this\n\t}));\n};\n\nViewWidget.prototype.getValueAsHtmlEncoded = function() {\n\treturn $tw.utils.htmlEncode(this.getValueAsText());\n};\n\nViewWidget.prototype.getValueAsUrlEncoded = function() {\n\treturn encodeURIComponent(this.getValueAsText());\n};\n\nViewWidget.prototype.getValueAsDoubleUrlEncoded = function() {\n\treturn encodeURIComponent(encodeURIComponent(this.getValueAsText()));\n};\n\nViewWidget.prototype.getValueAsDate = function(format) {\n\tformat = format || \"YYYY MM DD 0hh:0mm\";\n\tvar value = $tw.utils.parseDate(this.getValue());\n\tif(value && $tw.utils.isDate(value) && value.toString() !== \"Invalid Date\") {\n\t\treturn $tw.utils.formatDateString(value,format);\n\t} else {\n\t\treturn \"\";\n\t}\n};\n\nViewWidget.prototype.getValueAsRelativeDate = function(format) {\n\tvar value = $tw.utils.parseDate(this.getValue());\n\tif(value && $tw.utils.isDate(value) && value.toString() !== \"Invalid Date\") {\n\t\treturn $tw.utils.getRelativeDate((new Date()) - (new Date(value))).description;\n\t} else {\n\t\treturn \"\";\n\t}\n};\n\nViewWidget.prototype.getValueAsStrippedComments = function() {\n\tvar lines = this.getValueAsText().split(\"\\n\"),\n\t\tout = [];\n\tfor(var line=0; line<lines.length; line++) {\n\t\tvar text = lines[line];\n\t\tif(!/^\\s*\\/\\/#/.test(text)) {\n\t\t\tout.push(text);\n\t\t}\n\t}\n\treturn out.join(\"\\n\");\n};\n\nViewWidget.prototype.getValueAsJsEncoded = function() {\n\treturn $tw.utils.stringify(this.getValueAsText());\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nViewWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes.template || changedAttributes.format || changedTiddlers[this.viewTitle]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn false;\t\n\t}\n};\n\nexports.view = ViewWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/widget.js": {
"title": "$:/core/modules/widgets/widget.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/widget.js\ntype: application/javascript\nmodule-type: widget\n\nWidget base class\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nCreate a widget object for a parse tree node\n\tparseTreeNode: reference to the parse tree node to be rendered\n\toptions: see below\nOptions include:\n\twiki: mandatory reference to wiki associated with this render tree\n\tparentWidget: optional reference to a parent renderer node for the context chain\n\tdocument: optional document object to use instead of global document\n*/\nvar Widget = function(parseTreeNode,options) {\n\tif(arguments.length > 0) {\n\t\tthis.initialise(parseTreeNode,options);\n\t}\n};\n\n/*\nInitialise widget properties. These steps are pulled out of the constructor so that we can reuse them in subclasses\n*/\nWidget.prototype.initialise = function(parseTreeNode,options) {\n\toptions = options || {};\n\t// Save widget info\n\tthis.parseTreeNode = parseTreeNode;\n\tthis.wiki = options.wiki;\n\tthis.parentWidget = options.parentWidget;\n\tthis.variablesConstructor = function() {};\n\tthis.variablesConstructor.prototype = this.parentWidget ? this.parentWidget.variables : {};\n\tthis.variables = new this.variablesConstructor();\n\tthis.document = options.document;\n\tthis.attributes = {};\n\tthis.children = [];\n\tthis.domNodes = [];\n\tthis.eventListeners = {};\n\t// Hashmap of the widget classes\n\tif(!this.widgetClasses) {\n\t\tWidget.prototype.widgetClasses = $tw.modules.applyMethods(\"widget\");\n\t}\n};\n\n/*\nRender this widget into the DOM\n*/\nWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nWidget.prototype.execute = function() {\n\tthis.makeChildWidgets();\n};\n\n/*\nSet the value of a context variable\nname: name of the variable\nvalue: value of the variable\nparams: array of {name:, default:} for each parameter\nisMacroDefinition: true if the variable is set via a \\define macro pragma (and hence should have variable substitution performed)\n*/\nWidget.prototype.setVariable = function(name,value,params,isMacroDefinition) {\n\tthis.variables[name] = {value: value, params: params, isMacroDefinition: !!isMacroDefinition};\n};\n\n/*\nGet the prevailing value of a context variable\nname: name of variable\noptions: see below\nOptions include\nparams: array of {name:, value:} for each parameter\ndefaultValue: default value if the variable is not defined\n\nReturns an object with the following fields:\n\nparams: array of {name:,value:} of parameters passed to wikitext variables\ntext: text of variable, with parameters properly substituted\n*/\nWidget.prototype.getVariableInfo = function(name,options) {\n\toptions = options || {};\n\tvar actualParams = options.params || [],\n\t\tparentWidget = this.parentWidget;\n\t// Check for the variable defined in the parent widget (or an ancestor in the prototype chain)\n\tif(parentWidget && name in parentWidget.variables) {\n\t\tvar variable = parentWidget.variables[name],\n\t\t\tvalue = variable.value,\n\t\t\tparams = this.resolveVariableParameters(variable.params,actualParams);\n\t\t// Substitute any parameters specified in the definition\n\t\t$tw.utils.each(params,function(param) {\n\t\t\tvalue = $tw.utils.replaceString(value,new RegExp(\"\\\\$\" + $tw.utils.escapeRegExp(param.name) + \"\\\\$\",\"mg\"),param.value);\n\t\t});\n\t\t// Only substitute variable references if this variable was defined with the \\define pragma\n\t\tif(variable.isMacroDefinition) {\n\t\t\tvalue = this.substituteVariableReferences(value);\t\t\t\n\t\t}\n\t\treturn {\n\t\t\ttext: value,\n\t\t\tparams: params\n\t\t};\n\t}\n\t// If the variable doesn't exist in the parent widget then look for a macro module\n\treturn {\n\t\ttext: this.evaluateMacroModule(name,actualParams,options.defaultValue)\n\t};\n};\n\n/*\nSimplified version of getVariableInfo() that just returns the text\n*/\nWidget.prototype.getVariable = function(name,options) {\n\treturn this.getVariableInfo(name,options).text;\n};\n\nWidget.prototype.resolveVariableParameters = function(formalParams,actualParams) {\n\tformalParams = formalParams || [];\n\tactualParams = actualParams || [];\n\tvar nextAnonParameter = 0, // Next candidate anonymous parameter in macro call\n\t\tparamInfo, paramValue,\n\t\tresults = [];\n\t// Step through each of the parameters in the macro definition\n\tfor(var p=0; p<formalParams.length; p++) {\n\t\t// Check if we've got a macro call parameter with the same name\n\t\tparamInfo = formalParams[p];\n\t\tparamValue = undefined;\n\t\tfor(var m=0; m<actualParams.length; m++) {\n\t\t\tif(actualParams[m].name === paramInfo.name) {\n\t\t\t\tparamValue = actualParams[m].value;\n\t\t\t}\n\t\t}\n\t\t// If not, use the next available anonymous macro call parameter\n\t\twhile(nextAnonParameter < actualParams.length && actualParams[nextAnonParameter].name) {\n\t\t\tnextAnonParameter++;\n\t\t}\n\t\tif(paramValue === undefined && nextAnonParameter < actualParams.length) {\n\t\t\tparamValue = actualParams[nextAnonParameter++].value;\n\t\t}\n\t\t// If we've still not got a value, use the default, if any\n\t\tparamValue = paramValue || paramInfo[\"default\"] || \"\";\n\t\t// Store the parameter name and value\n\t\tresults.push({name: paramInfo.name, value: paramValue});\n\t}\n\treturn results;\n};\n\nWidget.prototype.substituteVariableReferences = function(text) {\n\tvar self = this;\n\treturn (text || \"\").replace(/\\$\\(([^\\)\\$]+)\\)\\$/g,function(match,p1,offset,string) {\n\t\treturn self.getVariable(p1,{defaultValue: \"\"});\n\t});\n};\n\nWidget.prototype.evaluateMacroModule = function(name,actualParams,defaultValue) {\n\tif($tw.utils.hop($tw.macros,name)) {\n\t\tvar macro = $tw.macros[name],\n\t\t\targs = [];\n\t\tif(macro.params.length > 0) {\n\t\t\tvar nextAnonParameter = 0, // Next candidate anonymous parameter in macro call\n\t\t\t\tparamInfo, paramValue;\n\t\t\t// Step through each of the parameters in the macro definition\n\t\t\tfor(var p=0; p<macro.params.length; p++) {\n\t\t\t\t// Check if we've got a macro call parameter with the same name\n\t\t\t\tparamInfo = macro.params[p];\n\t\t\t\tparamValue = undefined;\n\t\t\t\tfor(var m=0; m<actualParams.length; m++) {\n\t\t\t\t\tif(actualParams[m].name === paramInfo.name) {\n\t\t\t\t\t\tparamValue = actualParams[m].value;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// If not, use the next available anonymous macro call parameter\n\t\t\t\twhile(nextAnonParameter < actualParams.length && actualParams[nextAnonParameter].name) {\n\t\t\t\t\tnextAnonParameter++;\n\t\t\t\t}\n\t\t\t\tif(paramValue === undefined && nextAnonParameter < actualParams.length) {\n\t\t\t\t\tparamValue = actualParams[nextAnonParameter++].value;\n\t\t\t\t}\n\t\t\t\t// If we've still not got a value, use the default, if any\n\t\t\t\tparamValue = paramValue || paramInfo[\"default\"] || \"\";\n\t\t\t\t// Save the parameter\n\t\t\t\targs.push(paramValue);\n\t\t\t}\n\t\t}\n\t\telse for(var i=0; i<actualParams.length; ++i) {\n\t\t\targs.push(actualParams[i].value);\n\t\t}\n\t\treturn (macro.run.apply(this,args) || \"\").toString();\n\t} else {\n\t\treturn defaultValue;\n\t}\n};\n\n/*\nCheck whether a given context variable value exists in the parent chain\n*/\nWidget.prototype.hasVariable = function(name,value) {\n\tvar node = this;\n\twhile(node) {\n\t\tif($tw.utils.hop(node.variables,name) && node.variables[name].value === value) {\n\t\t\treturn true;\n\t\t}\n\t\tnode = node.parentWidget;\n\t}\n\treturn false;\n};\n\n/*\nConstruct a qualifying string based on a hash of concatenating the values of a given variable in the parent chain\n*/\nWidget.prototype.getStateQualifier = function(name) {\n\tthis.qualifiers = this.qualifiers || Object.create(null);\n\tname = name || \"transclusion\";\n\tif(this.qualifiers[name]) {\n\t\treturn this.qualifiers[name];\n\t} else {\n\t\tvar output = [],\n\t\t\tnode = this;\n\t\twhile(node && node.parentWidget) {\n\t\t\tif($tw.utils.hop(node.parentWidget.variables,name)) {\n\t\t\t\toutput.push(node.getVariable(name));\n\t\t\t}\n\t\t\tnode = node.parentWidget;\n\t\t}\n\t\tvar value = $tw.utils.hashString(output.join(\"\"));\n\t\tthis.qualifiers[name] = value;\n\t\treturn value;\n\t}\n};\n\n/*\nCompute the current values of the attributes of the widget. Returns a hashmap of the names of the attributes that have changed\n*/\nWidget.prototype.computeAttributes = function() {\n\tvar changedAttributes = {},\n\t\tself = this,\n\t\tvalue;\n\t$tw.utils.each(this.parseTreeNode.attributes,function(attribute,name) {\n\t\tif(attribute.type === \"filtered\") {\n\t\t\tvalue = self.wiki.filterTiddlers(attribute.filter,self)[0] || \"\";\n\t\t} else if(attribute.type === \"indirect\") {\n\t\t\tvalue = self.wiki.getTextReference(attribute.textReference,\"\",self.getVariable(\"currentTiddler\"));\n\t\t} else if(attribute.type === \"macro\") {\n\t\t\tvalue = self.getVariable(attribute.value.name,{params: attribute.value.params});\n\t\t} else { // String attribute\n\t\t\tvalue = attribute.value;\n\t\t}\n\t\t// Check whether the attribute has changed\n\t\tif(self.attributes[name] !== value) {\n\t\t\tself.attributes[name] = value;\n\t\t\tchangedAttributes[name] = true;\n\t\t}\n\t});\n\treturn changedAttributes;\n};\n\n/*\nCheck for the presence of an attribute\n*/\nWidget.prototype.hasAttribute = function(name) {\n\treturn $tw.utils.hop(this.attributes,name);\n};\n\n/*\nGet the value of an attribute\n*/\nWidget.prototype.getAttribute = function(name,defaultText) {\n\tif($tw.utils.hop(this.attributes,name)) {\n\t\treturn this.attributes[name];\n\t} else {\n\t\treturn defaultText;\n\t}\n};\n\n/*\nAssign the computed attributes of the widget to a domNode\noptions include:\nexcludeEventAttributes: ignores attributes whose name begins with \"on\"\n*/\nWidget.prototype.assignAttributes = function(domNode,options) {\n\toptions = options || {};\n\tvar self = this;\n\t$tw.utils.each(this.attributes,function(v,a) {\n\t\t// Check exclusions\n\t\tif(options.excludeEventAttributes && a.substr(0,2) === \"on\") {\n\t\t\tv = undefined;\n\t\t}\n\t\tif(v !== undefined) {\n\t\t\tvar b = a.split(\":\");\n\t\t\t// Setting certain attributes can cause a DOM error (eg xmlns on the svg element)\n\t\t\ttry {\n\t\t\t\tif (b.length == 2 && b[0] == \"xlink\"){\n\t\t\t\t\tdomNode.setAttributeNS(\"http://www.w3.org/1999/xlink\",b[1],v);\n\t\t\t\t} else {\n\t\t\t\t\tdomNode.setAttributeNS(null,a,v);\n\t\t\t\t}\n\t\t\t} catch(e) {\n\t\t\t}\n\t\t}\n\t});\n};\n\n/*\nMake child widgets correspondng to specified parseTreeNodes\n*/\nWidget.prototype.makeChildWidgets = function(parseTreeNodes) {\n\tthis.children = [];\n\tvar self = this;\n\t$tw.utils.each(parseTreeNodes || (this.parseTreeNode && this.parseTreeNode.children),function(childNode) {\n\t\tself.children.push(self.makeChildWidget(childNode));\n\t});\n};\n\n/*\nConstruct the widget object for a parse tree node\n*/\nWidget.prototype.makeChildWidget = function(parseTreeNode) {\n\tvar WidgetClass = this.widgetClasses[parseTreeNode.type];\n\tif(!WidgetClass) {\n\t\tWidgetClass = this.widgetClasses.text;\n\t\tparseTreeNode = {type: \"text\", text: \"Undefined widget '\" + parseTreeNode.type + \"'\"};\n\t}\n\treturn new WidgetClass(parseTreeNode,{\n\t\twiki: this.wiki,\n\t\tvariables: {},\n\t\tparentWidget: this,\n\t\tdocument: this.document\n\t});\n};\n\n/*\nGet the next sibling of this widget\n*/\nWidget.prototype.nextSibling = function() {\n\tif(this.parentWidget) {\n\t\tvar index = this.parentWidget.children.indexOf(this);\n\t\tif(index !== -1 && index < this.parentWidget.children.length-1) {\n\t\t\treturn this.parentWidget.children[index+1];\n\t\t}\n\t}\n\treturn null;\n};\n\n/*\nGet the previous sibling of this widget\n*/\nWidget.prototype.previousSibling = function() {\n\tif(this.parentWidget) {\n\t\tvar index = this.parentWidget.children.indexOf(this);\n\t\tif(index !== -1 && index > 0) {\n\t\t\treturn this.parentWidget.children[index-1];\n\t\t}\n\t}\n\treturn null;\n};\n\n/*\nRender the children of this widget into the DOM\n*/\nWidget.prototype.renderChildren = function(parent,nextSibling) {\n\t$tw.utils.each(this.children,function(childWidget) {\n\t\tchildWidget.render(parent,nextSibling);\n\t});\n};\n\n/*\nAdd a list of event listeners from an array [{type:,handler:},...]\n*/\nWidget.prototype.addEventListeners = function(listeners) {\n\tvar self = this;\n\t$tw.utils.each(listeners,function(listenerInfo) {\n\t\tself.addEventListener(listenerInfo.type,listenerInfo.handler);\n\t});\n};\n\n/*\nAdd an event listener\n*/\nWidget.prototype.addEventListener = function(type,handler) {\n\tvar self = this;\n\tif(typeof handler === \"string\") { // The handler is a method name on this widget\n\t\tthis.eventListeners[type] = function(event) {\n\t\t\treturn self[handler].call(self,event);\n\t\t};\n\t} else { // The handler is a function\n\t\tthis.eventListeners[type] = function(event) {\n\t\t\treturn handler.call(self,event);\n\t\t};\n\t}\n};\n\n/*\nDispatch an event to a widget. If the widget doesn't handle the event then it is also dispatched to the parent widget\n*/\nWidget.prototype.dispatchEvent = function(event) {\n\t// Dispatch the event if this widget handles it\n\tvar listener = this.eventListeners[event.type];\n\tif(listener) {\n\t\t// Don't propagate the event if the listener returned false\n\t\tif(!listener(event)) {\n\t\t\treturn false;\n\t\t}\n\t}\n\t// Dispatch the event to the parent widget\n\tif(this.parentWidget) {\n\t\treturn this.parentWidget.dispatchEvent(event);\n\t}\n\treturn true;\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nWidget.prototype.refresh = function(changedTiddlers) {\n\treturn this.refreshChildren(changedTiddlers);\n};\n\n/*\nRebuild a previously rendered widget\n*/\nWidget.prototype.refreshSelf = function() {\n\tvar nextSibling = this.findNextSiblingDomNode();\n\tthis.removeChildDomNodes();\n\tthis.render(this.parentDomNode,nextSibling);\n};\n\n/*\nRefresh all the children of a widget\n*/\nWidget.prototype.refreshChildren = function(changedTiddlers) {\n\tvar self = this,\n\t\trefreshed = false;\n\t$tw.utils.each(this.children,function(childWidget) {\n\t\trefreshed = childWidget.refresh(changedTiddlers) || refreshed;\n\t});\n\treturn refreshed;\n};\n\n/*\nFind the next sibling in the DOM to this widget. This is done by scanning the widget tree through all next siblings and their descendents that share the same parent DOM node\n*/\nWidget.prototype.findNextSiblingDomNode = function(startIndex) {\n\t// Refer to this widget by its index within its parents children\n\tvar parent = this.parentWidget,\n\t\tindex = startIndex !== undefined ? startIndex : parent.children.indexOf(this);\nif(index === -1) {\n\tthrow \"node not found in parents children\";\n}\n\t// Look for a DOM node in the later siblings\n\twhile(++index < parent.children.length) {\n\t\tvar domNode = parent.children[index].findFirstDomNode();\n\t\tif(domNode) {\n\t\t\treturn domNode;\n\t\t}\n\t}\n\t// Go back and look for later siblings of our parent if it has the same parent dom node\n\tvar grandParent = parent.parentWidget;\n\tif(grandParent && parent.parentDomNode === this.parentDomNode) {\n\t\tindex = grandParent.children.indexOf(parent);\n\t\tif(index !== -1) {\n\t\t\treturn parent.findNextSiblingDomNode(index);\n\t\t}\n\t}\n\treturn null;\n};\n\n/*\nFind the first DOM node generated by a widget or its children\n*/\nWidget.prototype.findFirstDomNode = function() {\n\t// Return the first dom node of this widget, if we've got one\n\tif(this.domNodes.length > 0) {\n\t\treturn this.domNodes[0];\n\t}\n\t// Otherwise, recursively call our children\n\tfor(var t=0; t<this.children.length; t++) {\n\t\tvar domNode = this.children[t].findFirstDomNode();\n\t\tif(domNode) {\n\t\t\treturn domNode;\n\t\t}\n\t}\n\treturn null;\n};\n\n/*\nRemove any DOM nodes created by this widget or its children\n*/\nWidget.prototype.removeChildDomNodes = function() {\n\t// If this widget has directly created DOM nodes, delete them and exit. This assumes that any child widgets are contained within the created DOM nodes, which would normally be the case\n\tif(this.domNodes.length > 0) {\n\t\t$tw.utils.each(this.domNodes,function(domNode) {\n\t\t\tdomNode.parentNode.removeChild(domNode);\n\t\t});\n\t\tthis.domNodes = [];\n\t} else {\n\t\t// Otherwise, ask the child widgets to delete their DOM nodes\n\t\t$tw.utils.each(this.children,function(childWidget) {\n\t\t\tchildWidget.removeChildDomNodes();\n\t\t});\n\t}\n};\n\n/*\nInvoke the action widgets that are descendents of the current widget.\n*/\nWidget.prototype.invokeActions = function(triggeringWidget,event) {\n\tvar handled = false;\n\t// For each child widget\n\tfor(var t=0; t<this.children.length; t++) {\n\t\tvar child = this.children[t];\n\t\t// Invoke the child if it is an action widget\n\t\tif(child.invokeAction) {\n\t\t\tchild.refreshSelf();\n\t\t\tif(child.invokeAction(triggeringWidget,event)) {\n\t\t\t\thandled = true;\n\t\t\t}\n\t\t}\n\t\t// Propagate through through the child if it permits it\n\t\tif(child.allowActionPropagation() && child.invokeActions(triggeringWidget,event)) {\n\t\t\thandled = true;\n\t\t}\n\t}\n\treturn handled;\n};\n\n/*\nInvoke the action widgets defined in a string\n*/\nWidget.prototype.invokeActionString = function(actions,triggeringWidget,event,variables) {\n\tactions = actions || \"\";\n\tvar parser = this.wiki.parseText(\"text/vnd.tiddlywiki\",actions,{\n\t\t\tparentWidget: this,\n\t\t\tdocument: this.document\n\t\t}),\n\t\twidgetNode = this.wiki.makeWidget(parser,{\n\t\t\tparentWidget: this,\n\t\t\tdocument: this.document,\n\t\t\tvariables: variables\n\t\t});\n\tvar container = this.document.createElement(\"div\");\n\twidgetNode.render(container,null);\n\treturn widgetNode.invokeActions(this,event);\n};\n\nWidget.prototype.allowActionPropagation = function() {\n\treturn true;\n};\n\nexports.widget = Widget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/widgets/wikify.js": {
"title": "$:/core/modules/widgets/wikify.js",
"text": "/*\\\ntitle: $:/core/modules/widgets/wikify.js\ntype: application/javascript\nmodule-type: widget\n\nWidget to wikify text into a variable\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar WikifyWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nWikifyWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nWikifyWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nWikifyWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.wikifyName = this.getAttribute(\"name\");\n\tthis.wikifyText = this.getAttribute(\"text\");\n\tthis.wikifyType = this.getAttribute(\"type\");\n\tthis.wikifyMode = this.getAttribute(\"mode\",\"block\");\n\tthis.wikifyOutput = this.getAttribute(\"output\",\"text\");\n\t// Create the parse tree\n\tthis.wikifyParser = this.wiki.parseText(this.wikifyType,this.wikifyText,{\n\t\t\tparseAsInline: this.wikifyMode === \"inline\"\n\t\t});\n\t// Create the widget tree \n\tthis.wikifyWidgetNode = this.wiki.makeWidget(this.wikifyParser,{\n\t\t\tdocument: $tw.fakeDocument,\n\t\t\tparentWidget: this\n\t\t});\n\t// Render the widget tree to the container\n\tthis.wikifyContainer = $tw.fakeDocument.createElement(\"div\");\n\tthis.wikifyWidgetNode.render(this.wikifyContainer,null);\n\tthis.wikifyResult = this.getResult();\n\t// Set context variable\n\tthis.setVariable(this.wikifyName,this.wikifyResult);\n\t// Construct the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nReturn the result string\n*/\nWikifyWidget.prototype.getResult = function() {\n\tvar result;\n\tswitch(this.wikifyOutput) {\n\t\tcase \"text\":\n\t\t\tresult = this.wikifyContainer.textContent;\n\t\t\tbreak;\n\t\tcase \"formattedtext\":\n\t\t\tresult = this.wikifyContainer.formattedTextContent;\n\t\t\tbreak;\n\t\tcase \"html\":\n\t\t\tresult = this.wikifyContainer.innerHTML;\n\t\t\tbreak;\n\t\tcase \"parsetree\":\n\t\t\tresult = JSON.stringify(this.wikifyParser.tree,0,$tw.config.preferences.jsonSpaces);\n\t\t\tbreak;\n\t\tcase \"widgettree\":\n\t\t\tresult = JSON.stringify(this.getWidgetTree(),0,$tw.config.preferences.jsonSpaces);\n\t\t\tbreak;\n\t}\n\treturn result;\n};\n\n/*\nReturn a string of the widget tree\n*/\nWikifyWidget.prototype.getWidgetTree = function() {\n\tvar copyNode = function(widgetNode,resultNode) {\n\t\t\tvar type = widgetNode.parseTreeNode.type;\n\t\t\tresultNode.type = type;\n\t\t\tswitch(type) {\n\t\t\t\tcase \"element\":\n\t\t\t\t\tresultNode.tag = widgetNode.parseTreeNode.tag;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"text\":\n\t\t\t\t\tresultNode.text = widgetNode.parseTreeNode.text;\n\t\t\t\t\tbreak;\t\n\t\t\t}\n\t\t\tif(Object.keys(widgetNode.attributes || {}).length > 0) {\n\t\t\t\tresultNode.attributes = {};\n\t\t\t\t$tw.utils.each(widgetNode.attributes,function(attr,attrName) {\n\t\t\t\t\tresultNode.attributes[attrName] = widgetNode.getAttribute(attrName);\n\t\t\t\t});\n\t\t\t}\n\t\t\tif(Object.keys(widgetNode.children || {}).length > 0) {\n\t\t\t\tresultNode.children = [];\n\t\t\t\t$tw.utils.each(widgetNode.children,function(widgetChildNode) {\n\t\t\t\t\tvar node = {};\n\t\t\t\t\tresultNode.children.push(node);\n\t\t\t\t\tcopyNode(widgetChildNode,node);\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\tresults = {};\n\tcopyNode(this.wikifyWidgetNode,results);\n\treturn results;\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nWikifyWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\t// Refresh ourselves entirely if any of our attributes have changed\n\tif(changedAttributes.name || changedAttributes.text || changedAttributes.type || changedAttributes.mode || changedAttributes.output) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\t// Refresh the widget tree\n\t\tif(this.wikifyWidgetNode.refresh(changedTiddlers)) {\n\t\t\t// Check if there was any change\n\t\t\tvar result = this.getResult();\n\t\t\tif(result !== this.wikifyResult) {\n\t\t\t\t// If so, save the change\n\t\t\t\tthis.wikifyResult = result;\n\t\t\t\tthis.setVariable(this.wikifyName,this.wikifyResult);\n\t\t\t\t// Refresh each of our child widgets\n\t\t\t\t$tw.utils.each(this.children,function(childWidget) {\n\t\t\t\t\tchildWidget.refreshSelf();\n\t\t\t\t});\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\t// Just refresh the children\n\t\treturn this.refreshChildren(changedTiddlers);\n\t}\n};\n\nexports.wikify = WikifyWidget;\n\n})();\n",
"type": "application/javascript",
"module-type": "widget"
},
"$:/core/modules/wiki-bulkops.js": {
"title": "$:/core/modules/wiki-bulkops.js",
"text": "/*\\\ntitle: $:/core/modules/wiki-bulkops.js\ntype: application/javascript\nmodule-type: wikimethod\n\nBulk tiddler operations such as rename.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nRename a tiddler, and relink any tags or lists that reference it.\n*/\nfunction renameTiddler(fromTitle,toTitle,options) {\n\tfromTitle = (fromTitle || \"\").trim();\n\ttoTitle = (toTitle || \"\").trim();\n\toptions = options || {};\n\tif(fromTitle && toTitle && fromTitle !== toTitle) {\n\t\t// Rename the tiddler itself\n\t\tvar oldTiddler = this.getTiddler(fromTitle),\n\t\t\tnewTiddler = new $tw.Tiddler(oldTiddler,{title: toTitle},this.getModificationFields());\n\t\tnewTiddler = $tw.hooks.invokeHook(\"th-renaming-tiddler\",newTiddler,oldTiddler);\n\t\tthis.addTiddler(newTiddler);\n\t\tthis.deleteTiddler(fromTitle);\n\t\t// Rename any tags or lists that reference it\n\t\tthis.relinkTiddler(fromTitle,toTitle,options)\n\t}\n}\n\n/*\nRelink any tags or lists that reference a given tiddler\n*/\nfunction relinkTiddler(fromTitle,toTitle,options) {\n\tvar self = this;\n\tfromTitle = (fromTitle || \"\").trim();\n\ttoTitle = (toTitle || \"\").trim();\n\toptions = options || {};\n\tif(fromTitle && toTitle && fromTitle !== toTitle) {\n\t\tthis.each(function(tiddler,title) {\n\t\t\tvar type = tiddler.fields.type || \"\";\n\t\t\t// Don't touch plugins or JavaScript modules\n\t\t\tif(!tiddler.fields[\"plugin-type\"] && type !== \"application/javascript\") {\n\t\t\t\tvar tags = (tiddler.fields.tags || []).slice(0),\n\t\t\t\t\tlist = (tiddler.fields.list || []).slice(0),\n\t\t\t\t\tisModified = false;\n\t\t\t\tif(!options.dontRenameInTags) {\n\t\t\t\t\t// Rename tags\n\t\t\t\t\t$tw.utils.each(tags,function (title,index) {\n\t\t\t\t\t\tif(title === fromTitle) {\nconsole.log(\"Renaming tag '\" + tags[index] + \"' to '\" + toTitle + \"' of tiddler '\" + tiddler.fields.title + \"'\");\n\t\t\t\t\t\t\ttags[index] = toTitle;\n\t\t\t\t\t\t\tisModified = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tif(!options.dontRenameInLists) {\n\t\t\t\t\t// Rename lists\n\t\t\t\t\t$tw.utils.each(list,function (title,index) {\n\t\t\t\t\t\tif(title === fromTitle) {\nconsole.log(\"Renaming list item '\" + list[index] + \"' to '\" + toTitle + \"' of tiddler '\" + tiddler.fields.title + \"'\");\n\t\t\t\t\t\t\tlist[index] = toTitle;\n\t\t\t\t\t\t\tisModified = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tif(isModified) {\n\t\t\t\t\tvar newTiddler = new $tw.Tiddler(tiddler,{tags: tags, list: list},self.getModificationFields())\n\t\t\t\t\tnewTiddler = $tw.hooks.invokeHook(\"th-relinking-tiddler\",newTiddler,tiddler);\n\t\t\t\t\tself.addTiddler(newTiddler);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n};\n\nexports.renameTiddler = renameTiddler;\nexports.relinkTiddler = relinkTiddler;\n\n})();\n",
"type": "application/javascript",
"module-type": "wikimethod"
},
"$:/core/modules/wiki.js": {
"title": "$:/core/modules/wiki.js",
"text": "/*\\\ntitle: $:/core/modules/wiki.js\ntype: application/javascript\nmodule-type: wikimethod\n\nExtension methods for the $tw.Wiki object\n\nAdds the following properties to the wiki object:\n\n* `eventListeners` is a hashmap by type of arrays of listener functions\n* `changedTiddlers` is a hashmap describing changes to named tiddlers since wiki change events were last dispatched. Each entry is a hashmap containing two fields:\n\tmodified: true/false\n\tdeleted: true/false\n* `changeCount` is a hashmap by tiddler title containing a numerical index that starts at zero and is incremented each time a tiddler is created changed or deleted\n* `caches` is a hashmap by tiddler title containing a further hashmap of named cache objects. Caches are automatically cleared when a tiddler is modified or deleted\n* `globalCache` is a hashmap by cache name of cache objects that are cleared whenever any tiddler change occurs\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar widget = require(\"$:/core/modules/widgets/widget.js\");\n\nvar USER_NAME_TITLE = \"$:/status/UserName\",\n\tTIMESTAMP_DISABLE_TITLE = \"$:/config/TimestampDisable\";\n\n/*\nGet the value of a text reference. Text references can have any of these forms:\n\t<tiddlertitle>\n\t<tiddlertitle>!!<fieldname>\n\t!!<fieldname> - specifies a field of the current tiddlers\n\t<tiddlertitle>##<index>\n*/\nexports.getTextReference = function(textRef,defaultText,currTiddlerTitle) {\n\tvar tr = $tw.utils.parseTextReference(textRef),\n\t\ttitle = tr.title || currTiddlerTitle;\n\tif(tr.field) {\n\t\tvar tiddler = this.getTiddler(title);\n\t\tif(tr.field === \"title\") { // Special case so we can return the title of a non-existent tiddler\n\t\t\treturn title;\n\t\t} else if(tiddler && $tw.utils.hop(tiddler.fields,tr.field)) {\n\t\t\treturn tiddler.getFieldString(tr.field);\n\t\t} else {\n\t\t\treturn defaultText;\n\t\t}\n\t} else if(tr.index) {\n\t\treturn this.extractTiddlerDataItem(title,tr.index,defaultText);\n\t} else {\n\t\treturn this.getTiddlerText(title,defaultText);\n\t}\n};\n\nexports.setTextReference = function(textRef,value,currTiddlerTitle) {\n\tvar tr = $tw.utils.parseTextReference(textRef),\n\t\ttitle = tr.title || currTiddlerTitle;\n\tthis.setText(title,tr.field,tr.index,value);\n};\n\nexports.setText = function(title,field,index,value,options) {\n\toptions = options || {};\n\tvar creationFields = options.suppressTimestamp ? {} : this.getCreationFields(),\n\t\tmodificationFields = options.suppressTimestamp ? {} : this.getModificationFields();\n\t// Check if it is a reference to a tiddler field\n\tif(index) {\n\t\tvar data = this.getTiddlerData(title,Object.create(null));\n\t\tif(value !== undefined) {\n\t\t\tdata[index] = value;\n\t\t} else {\n\t\t\tdelete data[index];\n\t\t}\n\t\tthis.setTiddlerData(title,data,modificationFields);\n\t} else {\n\t\tvar tiddler = this.getTiddler(title),\n\t\t\tfields = {title: title};\n\t\tfields[field || \"text\"] = value;\n\t\tthis.addTiddler(new $tw.Tiddler(creationFields,tiddler,fields,modificationFields));\n\t}\n};\n\nexports.deleteTextReference = function(textRef,currTiddlerTitle) {\n\tvar tr = $tw.utils.parseTextReference(textRef),\n\t\ttitle,tiddler,fields;\n\t// Check if it is a reference to a tiddler\n\tif(tr.title && !tr.field) {\n\t\tthis.deleteTiddler(tr.title);\n\t// Else check for a field reference\n\t} else if(tr.field) {\n\t\ttitle = tr.title || currTiddlerTitle;\n\t\ttiddler = this.getTiddler(title);\n\t\tif(tiddler && $tw.utils.hop(tiddler.fields,tr.field)) {\n\t\t\tfields = Object.create(null);\n\t\t\tfields[tr.field] = undefined;\n\t\t\tthis.addTiddler(new $tw.Tiddler(tiddler,fields,this.getModificationFields()));\n\t\t}\n\t}\n};\n\nexports.addEventListener = function(type,listener) {\n\tthis.eventListeners = this.eventListeners || {};\n\tthis.eventListeners[type] = this.eventListeners[type] || [];\n\tthis.eventListeners[type].push(listener);\t\n};\n\nexports.removeEventListener = function(type,listener) {\n\tvar listeners = this.eventListeners[type];\n\tif(listeners) {\n\t\tvar p = listeners.indexOf(listener);\n\t\tif(p !== -1) {\n\t\t\tlisteners.splice(p,1);\n\t\t}\n\t}\n};\n\nexports.dispatchEvent = function(type /*, args */) {\n\tvar args = Array.prototype.slice.call(arguments,1),\n\t\tlisteners = this.eventListeners[type];\n\tif(listeners) {\n\t\tfor(var p=0; p<listeners.length; p++) {\n\t\t\tvar listener = listeners[p];\n\t\t\tlistener.apply(listener,args);\n\t\t}\n\t}\n};\n\n/*\nCauses a tiddler to be marked as changed, incrementing the change count, and triggers event handlers.\nThis method should be called after the changes it describes have been made to the wiki.tiddlers[] array.\n\ttitle: Title of tiddler\n\tisDeleted: defaults to false (meaning the tiddler has been created or modified),\n\t\ttrue if the tiddler has been deleted\n*/\nexports.enqueueTiddlerEvent = function(title,isDeleted) {\n\t// Record the touch in the list of changed tiddlers\n\tthis.changedTiddlers = this.changedTiddlers || Object.create(null);\n\tthis.changedTiddlers[title] = this.changedTiddlers[title] || Object.create(null);\n\tthis.changedTiddlers[title][isDeleted ? \"deleted\" : \"modified\"] = true;\n\t// Increment the change count\n\tthis.changeCount = this.changeCount || Object.create(null);\n\tif($tw.utils.hop(this.changeCount,title)) {\n\t\tthis.changeCount[title]++;\n\t} else {\n\t\tthis.changeCount[title] = 1;\n\t}\n\t// Trigger events\n\tthis.eventListeners = this.eventListeners || {};\n\tif(!this.eventsTriggered) {\n\t\tvar self = this;\n\t\t$tw.utils.nextTick(function() {\n\t\t\tvar changes = self.changedTiddlers;\n\t\t\tself.changedTiddlers = Object.create(null);\n\t\t\tself.eventsTriggered = false;\n\t\t\tif($tw.utils.count(changes) > 0) {\n\t\t\t\tself.dispatchEvent(\"change\",changes);\n\t\t\t}\n\t\t});\n\t\tthis.eventsTriggered = true;\n\t}\n};\n\nexports.getSizeOfTiddlerEventQueue = function() {\n\treturn $tw.utils.count(this.changedTiddlers);\n};\n\nexports.clearTiddlerEventQueue = function() {\n\tthis.changedTiddlers = Object.create(null);\n\tthis.changeCount = Object.create(null);\n};\n\nexports.getChangeCount = function(title) {\n\tthis.changeCount = this.changeCount || Object.create(null);\n\tif($tw.utils.hop(this.changeCount,title)) {\n\t\treturn this.changeCount[title];\n\t} else {\n\t\treturn 0;\n\t}\n};\n\n/*\nGenerate an unused title from the specified base\n*/\nexports.generateNewTitle = function(baseTitle,options) {\n\toptions = options || {};\n\tvar c = 0,\n\t\ttitle = baseTitle;\n\twhile(this.tiddlerExists(title) || this.isShadowTiddler(title) || this.findDraft(title)) {\n\t\ttitle = baseTitle + \n\t\t\t(options.prefix || \" \") + \n\t\t\t(++c);\n\t}\n\treturn title;\n};\n\nexports.isSystemTiddler = function(title) {\n\treturn title && title.indexOf(\"$:/\") === 0;\n};\n\nexports.isTemporaryTiddler = function(title) {\n\treturn title && title.indexOf(\"$:/temp/\") === 0;\n};\n\nexports.isImageTiddler = function(title) {\n\tvar tiddler = this.getTiddler(title);\n\tif(tiddler) {\t\t\n\t\tvar contentTypeInfo = $tw.config.contentTypeInfo[tiddler.fields.type || \"text/vnd.tiddlywiki\"];\n\t\treturn !!contentTypeInfo && contentTypeInfo.flags.indexOf(\"image\") !== -1;\n\t} else {\n\t\treturn null;\n\t}\n};\n\n/*\nLike addTiddler() except it will silently reject any plugin tiddlers that are older than the currently loaded version. Returns true if the tiddler was imported\n*/\nexports.importTiddler = function(tiddler) {\n\tvar existingTiddler = this.getTiddler(tiddler.fields.title);\n\t// Check if we're dealing with a plugin\n\tif(tiddler && tiddler.hasField(\"plugin-type\") && tiddler.hasField(\"version\") && existingTiddler && existingTiddler.hasField(\"plugin-type\") && existingTiddler.hasField(\"version\")) {\n\t\t// Reject the incoming plugin if it is older\n\t\tif(!$tw.utils.checkVersions(tiddler.fields.version,existingTiddler.fields.version)) {\n\t\t\treturn false;\n\t\t}\n\t}\n\t// Fall through to adding the tiddler\n\tthis.addTiddler(tiddler);\n\treturn true;\n};\n\n/*\nReturn a hashmap of the fields that should be set when a tiddler is created\n*/\nexports.getCreationFields = function() {\n\tif(this.getTiddlerText(TIMESTAMP_DISABLE_TITLE,\"\").toLowerCase() !== \"yes\") {\n\t\tvar fields = {\n\t\t\t\tcreated: new Date()\n\t\t\t},\n\t\t\tcreator = this.getTiddlerText(USER_NAME_TITLE);\n\t\tif(creator) {\n\t\t\tfields.creator = creator;\n\t\t}\n\t\treturn fields;\n\t} else {\n\t\treturn {};\n\t}\n};\n\n/*\nReturn a hashmap of the fields that should be set when a tiddler is modified\n*/\nexports.getModificationFields = function() {\n\tif(this.getTiddlerText(TIMESTAMP_DISABLE_TITLE,\"\").toLowerCase() !== \"yes\") {\n\t\tvar fields = Object.create(null),\n\t\t\tmodifier = this.getTiddlerText(USER_NAME_TITLE);\n\t\tfields.modified = new Date();\n\t\tif(modifier) {\n\t\t\tfields.modifier = modifier;\n\t\t}\n\t\treturn fields;\n\t} else {\n\t\treturn {};\n\t}\n};\n\n/*\nReturn a sorted array of tiddler titles. Options include:\nsortField: field to sort by\nexcludeTag: tag to exclude\nincludeSystem: whether to include system tiddlers (defaults to false)\n*/\nexports.getTiddlers = function(options) {\n\toptions = options || Object.create(null);\n\tvar self = this,\n\t\tsortField = options.sortField || \"title\",\n\t\ttiddlers = [], t, titles = [];\n\tthis.each(function(tiddler,title) {\n\t\tif(options.includeSystem || !self.isSystemTiddler(title)) {\n\t\t\tif(!options.excludeTag || !tiddler.hasTag(options.excludeTag)) {\n\t\t\t\ttiddlers.push(tiddler);\n\t\t\t}\n\t\t}\n\t});\n\ttiddlers.sort(function(a,b) {\n\t\tvar aa = a.fields[sortField].toLowerCase() || \"\",\n\t\t\tbb = b.fields[sortField].toLowerCase() || \"\";\n\t\tif(aa < bb) {\n\t\t\treturn -1;\n\t\t} else {\n\t\t\tif(aa > bb) {\n\t\t\t\treturn 1;\n\t\t\t} else {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t});\n\tfor(t=0; t<tiddlers.length; t++) {\n\t\ttitles.push(tiddlers[t].fields.title);\n\t}\n\treturn titles;\n};\n\nexports.countTiddlers = function(excludeTag) {\n\tvar tiddlers = this.getTiddlers({excludeTag: excludeTag});\n\treturn $tw.utils.count(tiddlers);\n};\n\n/*\nReturns a function iterator(callback) that iterates through the specified titles, and invokes the callback with callback(tiddler,title)\n*/\nexports.makeTiddlerIterator = function(titles) {\n\tvar self = this;\n\tif(!$tw.utils.isArray(titles)) {\n\t\ttitles = Object.keys(titles);\n\t} else {\n\t\ttitles = titles.slice(0);\n\t}\n\treturn function(callback) {\n\t\ttitles.forEach(function(title) {\n\t\t\tcallback(self.getTiddler(title),title);\n\t\t});\n\t};\n};\n\n/*\nSort an array of tiddler titles by a specified field\n\ttitles: array of titles (sorted in place)\n\tsortField: name of field to sort by\n\tisDescending: true if the sort should be descending\n\tisCaseSensitive: true if the sort should consider upper and lower case letters to be different\n*/\nexports.sortTiddlers = function(titles,sortField,isDescending,isCaseSensitive,isNumeric,isAlphaNumeric) {\n\tvar self = this;\n\ttitles.sort(function(a,b) {\n\t\tvar x,y,\n\t\t\tcompareNumbers = function(x,y) {\n\t\t\t\tvar result = \n\t\t\t\t\tisNaN(x) && !isNaN(y) ? (isDescending ? -1 : 1) :\n\t\t\t\t\t!isNaN(x) && isNaN(y) ? (isDescending ? 1 : -1) :\n\t\t\t\t\t\t\t\t\t\t\t(isDescending ? y - x : x - y);\n\t\t\t\treturn result;\n\t\t\t};\n\t\tif(sortField !== \"title\") {\n\t\t\tvar tiddlerA = self.getTiddler(a),\n\t\t\t\ttiddlerB = self.getTiddler(b);\n\t\t\tif(tiddlerA) {\n\t\t\t\ta = tiddlerA.fields[sortField] || \"\";\n\t\t\t} else {\n\t\t\t\ta = \"\";\n\t\t\t}\n\t\t\tif(tiddlerB) {\n\t\t\t\tb = tiddlerB.fields[sortField] || \"\";\n\t\t\t} else {\n\t\t\t\tb = \"\";\n\t\t\t}\n\t\t}\n\t\tx = Number(a);\n\t\ty = Number(b);\n\t\tif(isNumeric && (!isNaN(x) || !isNaN(y))) {\n\t\t\treturn compareNumbers(x,y);\n\t\t} else if(isAlphaNumeric) {\n\t\t\treturn isDescending ? b.localeCompare(a,undefined,{numeric: true,sensitivity: \"base\"}) : a.localeCompare(b,undefined,{numeric: true,sensitivity: \"base\"});\n\t\t} else if($tw.utils.isDate(a) && $tw.utils.isDate(b)) {\n\t\t\treturn isDescending ? b - a : a - b;\n\t\t} else {\n\t\t\ta = String(a);\n\t\t\tb = String(b);\n\t\t\tif(!isCaseSensitive) {\n\t\t\t\ta = a.toLowerCase();\n\t\t\t\tb = b.toLowerCase();\n\t\t\t}\n\t\t\treturn isDescending ? b.localeCompare(a) : a.localeCompare(b);\n\t\t}\n\t});\n};\n\n/*\nFor every tiddler invoke a callback(title,tiddler) with `this` set to the wiki object. Options include:\nsortField: field to sort by\nexcludeTag: tag to exclude\nincludeSystem: whether to include system tiddlers (defaults to false)\n*/\nexports.forEachTiddler = function(/* [options,]callback */) {\n\tvar arg = 0,\n\t\toptions = arguments.length >= 2 ? arguments[arg++] : {},\n\t\tcallback = arguments[arg++],\n\t\ttitles = this.getTiddlers(options),\n\t\tt, tiddler;\n\tfor(t=0; t<titles.length; t++) {\n\t\ttiddler = this.getTiddler(titles[t]);\n\t\tif(tiddler) {\n\t\t\tcallback.call(this,tiddler.fields.title,tiddler);\n\t\t}\n\t}\n};\n\n/*\nReturn an array of tiddler titles that are directly linked from the specified tiddler\n*/\nexports.getTiddlerLinks = function(title) {\n\tvar self = this;\n\t// We'll cache the links so they only get computed if the tiddler changes\n\treturn this.getCacheForTiddler(title,\"links\",function() {\n\t\t// Parse the tiddler\n\t\tvar parser = self.parseTiddler(title);\n\t\t// Count up the links\n\t\tvar links = [],\n\t\t\tcheckParseTree = function(parseTree) {\n\t\t\t\tfor(var t=0; t<parseTree.length; t++) {\n\t\t\t\t\tvar parseTreeNode = parseTree[t];\n\t\t\t\t\tif(parseTreeNode.type === \"link\" && parseTreeNode.attributes.to && parseTreeNode.attributes.to.type === \"string\") {\n\t\t\t\t\t\tvar value = parseTreeNode.attributes.to.value;\n\t\t\t\t\t\tif(links.indexOf(value) === -1) {\n\t\t\t\t\t\t\tlinks.push(value);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif(parseTreeNode.children) {\n\t\t\t\t\t\tcheckParseTree(parseTreeNode.children);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\t\tif(parser) {\n\t\t\tcheckParseTree(parser.tree);\n\t\t}\n\t\treturn links;\n\t});\n};\n\n/*\nReturn an array of tiddler titles that link to the specified tiddler\n*/\nexports.getTiddlerBacklinks = function(targetTitle) {\n\tvar self = this,\n\t\tbacklinks = [];\n\tthis.forEachTiddler(function(title,tiddler) {\n\t\tvar links = self.getTiddlerLinks(title);\n\t\tif(links.indexOf(targetTitle) !== -1) {\n\t\t\tbacklinks.push(title);\n\t\t}\n\t});\n\treturn backlinks;\n};\n\n/*\nReturn a hashmap of tiddler titles that are referenced but not defined. Each value is the number of times the missing tiddler is referenced\n*/\nexports.getMissingTitles = function() {\n\tvar self = this,\n\t\tmissing = [];\n// We should cache the missing tiddler list, even if we recreate it every time any tiddler is modified\n\tthis.forEachTiddler(function(title,tiddler) {\n\t\tvar links = self.getTiddlerLinks(title);\n\t\t$tw.utils.each(links,function(link) {\n\t\t\tif((!self.tiddlerExists(link) && !self.isShadowTiddler(link)) && missing.indexOf(link) === -1) {\n\t\t\t\tmissing.push(link);\n\t\t\t}\n\t\t});\n\t});\n\treturn missing;\n};\n\nexports.getOrphanTitles = function() {\n\tvar self = this,\n\t\torphans = this.getTiddlers();\n\tthis.forEachTiddler(function(title,tiddler) {\n\t\tvar links = self.getTiddlerLinks(title);\n\t\t$tw.utils.each(links,function(link) {\n\t\t\tvar p = orphans.indexOf(link);\n\t\t\tif(p !== -1) {\n\t\t\t\torphans.splice(p,1);\n\t\t\t}\n\t\t});\n\t});\n\treturn orphans; // Todo\n};\n\n/*\nRetrieves a list of the tiddler titles that are tagged with a given tag\n*/\nexports.getTiddlersWithTag = function(tag) {\n\tvar self = this;\n\treturn this.getGlobalCache(\"taglist-\" + tag,function() {\n\t\tvar tagmap = self.getTagMap();\n\t\treturn self.sortByList(tagmap[tag],tag);\n\t});\n};\n\n/*\nGet a hashmap by tag of arrays of tiddler titles\n*/\nexports.getTagMap = function() {\n\tvar self = this;\n\treturn this.getGlobalCache(\"tagmap\",function() {\n\t\tvar tags = Object.create(null),\n\t\t\tstoreTags = function(tagArray,title) {\n\t\t\t\tif(tagArray) {\n\t\t\t\t\tfor(var index=0; index<tagArray.length; index++) {\n\t\t\t\t\t\tvar tag = tagArray[index];\n\t\t\t\t\t\tif($tw.utils.hop(tags,tag)) {\n\t\t\t\t\t\t\ttags[tag].push(title);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\ttags[tag] = [title];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\ttitle, tiddler;\n\t\t// Collect up all the tags\n\t\tself.eachShadow(function(tiddler,title) {\n\t\t\tif(!self.tiddlerExists(title)) {\n\t\t\t\ttiddler = self.getTiddler(title);\n\t\t\t\tstoreTags(tiddler.fields.tags,title);\n\t\t\t}\n\t\t});\n\t\tself.each(function(tiddler,title) {\n\t\t\tstoreTags(tiddler.fields.tags,title);\n\t\t});\n\t\treturn tags;\n\t});\n};\n\n/*\nLookup a given tiddler and return a list of all the tiddlers that include it in the specified list field\n*/\nexports.findListingsOfTiddler = function(targetTitle,fieldName) {\n\tfieldName = fieldName || \"list\";\n\tvar titles = [];\n\tthis.each(function(tiddler,title) {\n\t\tvar list = $tw.utils.parseStringArray(tiddler.fields[fieldName]);\n\t\tif(list && list.indexOf(targetTitle) !== -1) {\n\t\t\ttitles.push(title);\n\t\t}\n\t});\n\treturn titles;\n};\n\n/*\nSorts an array of tiddler titles according to an ordered list\n*/\nexports.sortByList = function(array,listTitle) {\n\tvar self = this,\n\t\treplacedTitles = Object.create(null);\n\tfunction replaceItem(title) {\n\t\tif(!$tw.utils.hop(replacedTitles, title)) {\n\t\t\treplacedTitles[title] = true;\n\t\t\tvar newPos = -1,\n\t\t\t\ttiddler = self.getTiddler(title);\n\t\t\tif(tiddler) {\n\t\t\t\tvar beforeTitle = tiddler.fields[\"list-before\"],\n\t\t\t\t\tafterTitle = tiddler.fields[\"list-after\"];\n\t\t\t\tif(beforeTitle === \"\") {\n\t\t\t\t\tnewPos = 0;\n\t\t\t\t} else if(afterTitle === \"\") {\n\t\t\t\t\tnewPos = titles.length;\n\t\t\t\t} else if(beforeTitle) {\n\t\t\t\t\treplaceItem(beforeTitle);\n\t\t\t\t\tnewPos = titles.indexOf(beforeTitle);\n\t\t\t\t} else if(afterTitle) {\n\t\t\t\t\treplaceItem(afterTitle);\n\t\t\t\t\tnewPos = titles.indexOf(afterTitle);\n\t\t\t\t\tif(newPos >= 0) {\n\t\t\t\t\t\t++newPos;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// We get the currPos //after// figuring out the newPos, because recursive replaceItem calls might alter title's currPos\n\t\t\t\tvar currPos = titles.indexOf(title);\n\t\t\t\tif(newPos === -1) {\n\t\t\t\t\tnewPos = currPos;\n\t\t\t\t}\n\t\t\t\tif(currPos >= 0 && newPos !== currPos) {\n\t\t\t\t\ttitles.splice(currPos,1);\n\t\t\t\t\tif(newPos >= currPos) {\n\t\t\t\t\t\tnewPos--;\n\t\t\t\t\t}\n\t\t\t\t\ttitles.splice(newPos,0,title);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tvar list = this.getTiddlerList(listTitle);\n\tif(!array || array.length === 0) {\n\t\treturn [];\n\t} else {\n\t\tvar titles = [], t, title;\n\t\t// First place any entries that are present in the list\n\t\tfor(t=0; t<list.length; t++) {\n\t\t\ttitle = list[t];\n\t\t\tif(array.indexOf(title) !== -1) {\n\t\t\t\ttitles.push(title);\n\t\t\t}\n\t\t}\n\t\t// Then place any remaining entries\n\t\tfor(t=0; t<array.length; t++) {\n\t\t\ttitle = array[t];\n\t\t\tif(list.indexOf(title) === -1) {\n\t\t\t\ttitles.push(title);\n\t\t\t}\n\t\t}\n\t\t// Finally obey the list-before and list-after fields of each tiddler in turn\n\t\tvar sortedTitles = titles.slice(0);\n\t\tfor(t=0; t<sortedTitles.length; t++) {\n\t\t\ttitle = sortedTitles[t];\n\t\t\treplaceItem(title);\n\t\t}\n\t\treturn titles;\n\t}\n};\n\nexports.getSubTiddler = function(title,subTiddlerTitle) {\n\tvar bundleInfo = this.getPluginInfo(title) || this.getTiddlerDataCached(title);\n\tif(bundleInfo && bundleInfo.tiddlers) {\n\t\tvar subTiddler = bundleInfo.tiddlers[subTiddlerTitle];\n\t\tif(subTiddler) {\n\t\t\treturn new $tw.Tiddler(subTiddler);\n\t\t}\n\t}\n\treturn null;\n};\n\n/*\nRetrieve a tiddler as a JSON string of the fields\n*/\nexports.getTiddlerAsJson = function(title) {\n\tvar tiddler = this.getTiddler(title);\n\tif(tiddler) {\n\t\tvar fields = Object.create(null);\n\t\t$tw.utils.each(tiddler.fields,function(value,name) {\n\t\t\tfields[name] = tiddler.getFieldString(name);\n\t\t});\n\t\treturn JSON.stringify(fields);\n\t} else {\n\t\treturn JSON.stringify({title: title});\n\t}\n};\n\nexports.getTiddlersAsJson = function(filter) {\n\tvar tiddlers = this.filterTiddlers(filter),\n\t\tdata = [];\n\tfor(var t=0;t<tiddlers.length; t++) {\n\t\tvar tiddler = this.getTiddler(tiddlers[t]);\n\t\tif(tiddler) {\n\t\t\tvar fields = new Object();\n\t\t\tfor(var field in tiddler.fields) {\n\t\t\t\tfields[field] = tiddler.getFieldString(field);\n\t\t\t}\n\t\t\tdata.push(fields);\n\t\t}\n\t}\n\treturn JSON.stringify(data,null,$tw.config.preferences.jsonSpaces);\n};\n\n/*\nGet the content of a tiddler as a JavaScript object. How this is done depends on the type of the tiddler:\n\napplication/json: the tiddler JSON is parsed into an object\napplication/x-tiddler-dictionary: the tiddler is parsed as sequence of name:value pairs\n\nOther types currently just return null.\n\ntitleOrTiddler: string tiddler title or a tiddler object\ndefaultData: default data to be returned if the tiddler is missing or doesn't contain data\n\nNote that the same value is returned for repeated calls for the same tiddler data. The value is frozen to prevent modification; otherwise modifications would be visible to all callers\n*/\nexports.getTiddlerDataCached = function(titleOrTiddler,defaultData) {\n\tvar self = this,\n\t\ttiddler = titleOrTiddler;\n\tif(!(tiddler instanceof $tw.Tiddler)) {\n\t\ttiddler = this.getTiddler(tiddler);\t\n\t}\n\tif(tiddler) {\n\t\treturn this.getCacheForTiddler(tiddler.fields.title,\"data\",function() {\n\t\t\t// Return the frozen value\n\t\t\tvar value = self.getTiddlerData(tiddler.fields.title,undefined);\n\t\t\t$tw.utils.deepFreeze(value);\n\t\t\treturn value;\n\t\t}) || defaultData;\n\t} else {\n\t\treturn defaultData;\n\t}\n};\n\n/*\nAlternative, uncached version of getTiddlerDataCached(). The return value can be mutated freely and reused\n*/\nexports.getTiddlerData = function(titleOrTiddler,defaultData) {\n\tvar tiddler = titleOrTiddler,\n\t\tdata;\n\tif(!(tiddler instanceof $tw.Tiddler)) {\n\t\ttiddler = this.getTiddler(tiddler);\t\n\t}\n\tif(tiddler && tiddler.fields.text) {\n\t\tswitch(tiddler.fields.type) {\n\t\t\tcase \"application/json\":\n\t\t\t\t// JSON tiddler\n\t\t\t\ttry {\n\t\t\t\t\tdata = JSON.parse(tiddler.fields.text);\n\t\t\t\t} catch(ex) {\n\t\t\t\t\treturn defaultData;\n\t\t\t\t}\n\t\t\t\treturn data;\n\t\t\tcase \"application/x-tiddler-dictionary\":\n\t\t\t\treturn $tw.utils.parseFields(tiddler.fields.text);\n\t\t}\n\t}\n\treturn defaultData;\n};\n\n/*\nExtract an indexed field from within a data tiddler\n*/\nexports.extractTiddlerDataItem = function(titleOrTiddler,index,defaultText) {\n\tvar data = this.getTiddlerDataCached(titleOrTiddler,Object.create(null)),\n\t\ttext;\n\tif(data && $tw.utils.hop(data,index)) {\n\t\ttext = data[index];\n\t}\n\tif(typeof text === \"string\" || typeof text === \"number\") {\n\t\treturn text.toString();\n\t} else {\n\t\treturn defaultText;\n\t}\n};\n\n/*\nSet a tiddlers content to a JavaScript object. Currently this is done by setting the tiddler's type to \"application/json\" and setting the text to the JSON text of the data.\ntitle: title of tiddler\ndata: object that can be serialised to JSON\nfields: optional hashmap of additional tiddler fields to be set\n*/\nexports.setTiddlerData = function(title,data,fields) {\n\tvar existingTiddler = this.getTiddler(title),\n\t\tnewFields = {\n\t\t\ttitle: title\n\t};\n\tif(existingTiddler && existingTiddler.fields.type === \"application/x-tiddler-dictionary\") {\n\t\tnewFields.text = $tw.utils.makeTiddlerDictionary(data);\n\t} else {\n\t\tnewFields.type = \"application/json\";\n\t\tnewFields.text = JSON.stringify(data,null,$tw.config.preferences.jsonSpaces);\n\t}\n\tthis.addTiddler(new $tw.Tiddler(this.getCreationFields(),existingTiddler,fields,newFields,this.getModificationFields()));\n};\n\n/*\nReturn the content of a tiddler as an array containing each line\n*/\nexports.getTiddlerList = function(title,field,index) {\n\tif(index) {\n\t\treturn $tw.utils.parseStringArray(this.extractTiddlerDataItem(title,index,\"\"));\n\t}\n\tfield = field || \"list\";\n\tvar tiddler = this.getTiddler(title);\n\tif(tiddler) {\n\t\treturn ($tw.utils.parseStringArray(tiddler.fields[field]) || []).slice(0);\n\t}\n\treturn [];\n};\n\n// Return a named global cache object. Global cache objects are cleared whenever a tiddler change occurs\nexports.getGlobalCache = function(cacheName,initializer) {\n\tthis.globalCache = this.globalCache || Object.create(null);\n\tif($tw.utils.hop(this.globalCache,cacheName)) {\n\t\treturn this.globalCache[cacheName];\n\t} else {\n\t\tthis.globalCache[cacheName] = initializer();\n\t\treturn this.globalCache[cacheName];\n\t}\n};\n\nexports.clearGlobalCache = function() {\n\tthis.globalCache = Object.create(null);\n};\n\n// Return the named cache object for a tiddler. If the cache doesn't exist then the initializer function is invoked to create it\nexports.getCacheForTiddler = function(title,cacheName,initializer) {\n\tthis.caches = this.caches || Object.create(null);\n\tvar caches = this.caches[title];\n\tif(caches && caches[cacheName]) {\n\t\treturn caches[cacheName];\n\t} else {\n\t\tif(!caches) {\n\t\t\tcaches = Object.create(null);\n\t\t\tthis.caches[title] = caches;\n\t\t}\n\t\tcaches[cacheName] = initializer();\n\t\treturn caches[cacheName];\n\t}\n};\n\n// Clear all caches associated with a particular tiddler, or, if the title is null, clear all the caches for all the tiddlers\nexports.clearCache = function(title) {\n\tif(title) {\n\t\tthis.caches = this.caches || Object.create(null);\n\t\tif($tw.utils.hop(this.caches,title)) {\n\t\t\tdelete this.caches[title];\n\t\t}\n\t} else {\n\t\tthis.caches = Object.create(null);\n\t}\n};\n\nexports.initParsers = function(moduleType) {\n\t// Install the parser modules\n\t$tw.Wiki.parsers = {};\n\tvar self = this;\n\t$tw.modules.forEachModuleOfType(\"parser\",function(title,module) {\n\t\tfor(var f in module) {\n\t\t\tif($tw.utils.hop(module,f)) {\n\t\t\t\t$tw.Wiki.parsers[f] = module[f]; // Store the parser class\n\t\t\t}\n\t\t}\n\t});\n\t// Use the generic binary parser for any binary types not registered so far\n\tif($tw.Wiki.parsers[\"application/octet-stream\"]) {\n\t\tObject.keys($tw.config.contentTypeInfo).forEach(function(type) {\n\t\t\tif(!$tw.utils.hop($tw.Wiki.parsers,type) && $tw.config.contentTypeInfo[type].encoding === \"base64\") {\n\t\t\t\t$tw.Wiki.parsers[type] = $tw.Wiki.parsers[\"application/octet-stream\"];\n\t\t\t}\n\t\t});\t\t\n\t}\n};\n\n/*\nParse a block of text of a specified MIME type\n\ttype: content type of text to be parsed\n\ttext: text\n\toptions: see below\nOptions include:\n\tparseAsInline: if true, the text of the tiddler will be parsed as an inline run\n\t_canonical_uri: optional string of the canonical URI of this content\n*/\nexports.parseText = function(type,text,options) {\n\ttext = text || \"\";\n\toptions = options || {};\n\t// Select a parser\n\tvar Parser = $tw.Wiki.parsers[type];\n\tif(!Parser && $tw.utils.getFileExtensionInfo(type)) {\n\t\tParser = $tw.Wiki.parsers[$tw.utils.getFileExtensionInfo(type).type];\n\t}\n\tif(!Parser) {\n\t\tParser = $tw.Wiki.parsers[options.defaultType || \"text/vnd.tiddlywiki\"];\n\t}\n\tif(!Parser) {\n\t\treturn null;\n\t}\n\t// Return the parser instance\n\treturn new Parser(type,text,{\n\t\tparseAsInline: options.parseAsInline,\n\t\twiki: this,\n\t\t_canonical_uri: options._canonical_uri\n\t});\n};\n\n/*\nParse a tiddler according to its MIME type\n*/\nexports.parseTiddler = function(title,options) {\n\toptions = $tw.utils.extend({},options);\n\tvar cacheType = options.parseAsInline ? \"inlineParseTree\" : \"blockParseTree\",\n\t\ttiddler = this.getTiddler(title),\n\t\tself = this;\n\treturn tiddler ? this.getCacheForTiddler(title,cacheType,function() {\n\t\t\tif(tiddler.hasField(\"_canonical_uri\")) {\n\t\t\t\toptions._canonical_uri = tiddler.fields._canonical_uri;\n\t\t\t}\n\t\t\treturn self.parseText(tiddler.fields.type,tiddler.fields.text,options);\n\t\t}) : null;\n};\n\nexports.parseTextReference = function(title,field,index,options) {\n\tvar tiddler,text;\n\tif(options.subTiddler) {\n\t\ttiddler = this.getSubTiddler(title,options.subTiddler);\n\t} else {\n\t\ttiddler = this.getTiddler(title);\n\t\tif(field === \"text\" || (!field && !index)) {\n\t\t\tthis.getTiddlerText(title); // Force the tiddler to be lazily loaded\n\t\t\treturn this.parseTiddler(title,options);\n\t\t}\n\t}\n\tif(field === \"text\" || (!field && !index)) {\n\t\tif(tiddler && tiddler.fields) {\n\t\t\treturn this.parseText(tiddler.fields.type,tiddler.fields.text,options);\t\t\t\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t} else if(field) {\n\t\tif(field === \"title\") {\n\t\t\ttext = title;\n\t\t} else {\n\t\t\tif(!tiddler || !tiddler.hasField(field)) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\ttext = tiddler.fields[field];\n\t\t}\n\t\treturn this.parseText(\"text/vnd.tiddlywiki\",text.toString(),options);\n\t} else if(index) {\n\t\tthis.getTiddlerText(title); // Force the tiddler to be lazily loaded\n\t\ttext = this.extractTiddlerDataItem(tiddler,index,undefined);\n\t\tif(text === undefined) {\n\t\t\treturn null;\n\t\t}\n\t\treturn this.parseText(\"text/vnd.tiddlywiki\",text,options);\n\t}\n};\n\n/*\nMake a widget tree for a parse tree\nparser: parser object\noptions: see below\nOptions include:\ndocument: optional document to use\nvariables: hashmap of variables to set\nparentWidget: optional parent widget for the root node\n*/\nexports.makeWidget = function(parser,options) {\n\toptions = options || {};\n\tvar widgetNode = {\n\t\t\ttype: \"widget\",\n\t\t\tchildren: []\n\t\t},\n\t\tcurrWidgetNode = widgetNode;\n\t// Create set variable widgets for each variable\n\t$tw.utils.each(options.variables,function(value,name) {\n\t\tvar setVariableWidget = {\n\t\t\ttype: \"set\",\n\t\t\tattributes: {\n\t\t\t\tname: {type: \"string\", value: name},\n\t\t\t\tvalue: {type: \"string\", value: value}\n\t\t\t},\n\t\t\tchildren: []\n\t\t};\n\t\tcurrWidgetNode.children = [setVariableWidget];\n\t\tcurrWidgetNode = setVariableWidget;\n\t});\n\t// Add in the supplied parse tree nodes\n\tcurrWidgetNode.children = parser ? parser.tree : [];\n\t// Create the widget\n\treturn new widget.widget(widgetNode,{\n\t\twiki: this,\n\t\tdocument: options.document || $tw.fakeDocument,\n\t\tparentWidget: options.parentWidget\n\t});\n};\n\n/*\nMake a widget tree for transclusion\ntitle: target tiddler title\noptions: as for wiki.makeWidget() plus:\noptions.field: optional field to transclude (defaults to \"text\")\noptions.mode: transclusion mode \"inline\" or \"block\"\noptions.children: optional array of children for the transclude widget\noptions.importVariables: optional importvariables filter string for macros to be included\noptions.importPageMacros: optional boolean; if true, equivalent to passing \"[[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]\" to options.importVariables\n*/\nexports.makeTranscludeWidget = function(title,options) {\n\toptions = options || {};\n\tvar parseTreeDiv = {tree: [{\n\t\t\ttype: \"element\",\n\t\t\ttag: \"div\",\n\t\t\tchildren: []}]},\n\t\tparseTreeImportVariables = {\n\t\t\ttype: \"importvariables\",\n\t\t\tattributes: {\n\t\t\t\tfilter: {\n\t\t\t\t\tname: \"filter\",\n\t\t\t\t\ttype: \"string\"\n\t\t\t\t}\n\t\t\t},\n\t\t\tisBlock: false,\n\t\t\tchildren: []},\n\t\tparseTreeTransclude = {\n\t\t\ttype: \"transclude\",\n\t\t\tattributes: {\n\t\t\t\ttiddler: {\n\t\t\t\t\tname: \"tiddler\",\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tvalue: title}},\n\t\t\tisBlock: !options.parseAsInline};\n\tif(options.importVariables || options.importPageMacros) {\n\t\tif(options.importVariables) {\n\t\t\tparseTreeImportVariables.attributes.filter.value = options.importVariables;\n\t\t} else if(options.importPageMacros) {\n\t\t\tparseTreeImportVariables.attributes.filter.value = \"[[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]\";\n\t\t}\n\t\tparseTreeDiv.tree[0].children.push(parseTreeImportVariables);\n\t\tparseTreeImportVariables.children.push(parseTreeTransclude);\n\t} else {\n\t\tparseTreeDiv.tree[0].children.push(parseTreeTransclude);\n\t}\n\tif(options.field) {\n\t\tparseTreeTransclude.attributes.field = {type: \"string\", value: options.field};\n\t}\n\tif(options.mode) {\n\t\tparseTreeTransclude.attributes.mode = {type: \"string\", value: options.mode};\n\t}\n\tif(options.children) {\n\t\tparseTreeTransclude.children = options.children;\n\t}\n\treturn $tw.wiki.makeWidget(parseTreeDiv,options);\n};\n\n/*\nParse text in a specified format and render it into another format\n\toutputType: content type for the output\n\ttextType: content type of the input text\n\ttext: input text\n\toptions: see below\nOptions include:\nvariables: hashmap of variables to set\nparentWidget: optional parent widget for the root node\n*/\nexports.renderText = function(outputType,textType,text,options) {\n\toptions = options || {};\n\tvar parser = this.parseText(textType,text,options),\n\t\twidgetNode = this.makeWidget(parser,options);\n\tvar container = $tw.fakeDocument.createElement(\"div\");\n\twidgetNode.render(container,null);\n\treturn outputType === \"text/html\" ? container.innerHTML : container.textContent;\n};\n\n/*\nParse text from a tiddler and render it into another format\n\toutputType: content type for the output\n\ttitle: title of the tiddler to be rendered\n\toptions: see below\nOptions include:\nvariables: hashmap of variables to set\nparentWidget: optional parent widget for the root node\n*/\nexports.renderTiddler = function(outputType,title,options) {\n\toptions = options || {};\n\tvar parser = this.parseTiddler(title,options),\n\t\twidgetNode = this.makeWidget(parser,options);\n\tvar container = $tw.fakeDocument.createElement(\"div\");\n\twidgetNode.render(container,null);\n\treturn outputType === \"text/html\" ? container.innerHTML : (outputType === \"text/plain-formatted\" ? container.formattedTextContent : container.textContent);\n};\n\n/*\nReturn an array of tiddler titles that match a search string\n\ttext: The text string to search for\n\toptions: see below\nOptions available:\n\tsource: an iterator function for the source tiddlers, called source(iterator), where iterator is called as iterator(tiddler,title)\n\texclude: An array of tiddler titles to exclude from the search\n\tinvert: If true returns tiddlers that do not contain the specified string\n\tcaseSensitive: If true forces a case sensitive search\n\tfield: If specified, restricts the search to the specified field, or an array of field names\n\texcludeField: If true, the field options are inverted to specify the fields that are not to be searched\n\tThe search mode is determined by the first of these boolean flags to be true\n\t\tliteral: searches for literal string\n\t\twhitespace: same as literal except runs of whitespace are treated as a single space\n\t\tregexp: treats the search term as a regular expression\n\t\twords: (default) treats search string as a list of tokens, and matches if all tokens are found, regardless of adjacency or ordering\n*/\nexports.search = function(text,options) {\n\toptions = options || {};\n\tvar self = this,\n\t\tt,\n\t\tinvert = !!options.invert;\n\t// Convert the search string into a regexp for each term\n\tvar terms, searchTermsRegExps,\n\t\tflags = options.caseSensitive ? \"\" : \"i\";\n\tif(options.literal) {\n\t\tif(text.length === 0) {\n\t\t\tsearchTermsRegExps = null;\n\t\t} else {\n\t\t\tsearchTermsRegExps = [new RegExp(\"(\" + $tw.utils.escapeRegExp(text) + \")\",flags)];\n\t\t}\n\t} else if(options.whitespace) {\n\t\tterms = [];\n\t\t$tw.utils.each(text.split(/\\s+/g),function(term) {\n\t\t\tif(term) {\n\t\t\t\tterms.push($tw.utils.escapeRegExp(term));\n\t\t\t}\n\t\t});\n\t\tsearchTermsRegExps = [new RegExp(\"(\" + terms.join(\"\\\\s+\") + \")\",flags)];\n\t} else if(options.regexp) {\n\t\ttry {\n\t\t\tsearchTermsRegExps = [new RegExp(\"(\" + text + \")\",flags)];\t\t\t\n\t\t} catch(e) {\n\t\t\tsearchTermsRegExps = null;\n\t\t\tconsole.log(\"Regexp error parsing /(\" + text + \")/\" + flags + \": \",e);\n\t\t}\n\t} else {\n\t\tterms = text.split(/ +/);\n\t\tif(terms.length === 1 && terms[0] === \"\") {\n\t\t\tsearchTermsRegExps = null;\n\t\t} else {\n\t\t\tsearchTermsRegExps = [];\n\t\t\tfor(t=0; t<terms.length; t++) {\n\t\t\t\tsearchTermsRegExps.push(new RegExp(\"(\" + $tw.utils.escapeRegExp(terms[t]) + \")\",flags));\n\t\t\t}\n\t\t}\n\t}\n\t// Accumulate the array of fields to be searched or excluded from the search\n\tvar fields = [];\n\tif(options.field) {\n\t\tif($tw.utils.isArray(options.field)) {\n\t\t\t$tw.utils.each(options.field,function(fieldName) {\n\t\t\t\tif(fieldName) {\n\t\t\t\t\tfields.push(fieldName);\t\t\t\t\t\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tfields.push(options.field);\n\t\t}\n\t}\n\t// Use default fields if none specified and we're not excluding fields (excluding fields with an empty field array is the same as searching all fields)\n\tif(fields.length === 0 && !options.excludeField) {\n\t\tfields.push(\"title\");\n\t\tfields.push(\"tags\");\n\t\tfields.push(\"text\");\n\t}\n\t// Function to check a given tiddler for the search term\n\tvar searchTiddler = function(title) {\n\t\tif(!searchTermsRegExps) {\n\t\t\treturn true;\n\t\t}\n\t\tvar notYetFound = searchTermsRegExps.slice();\n\n\t\tvar tiddler = self.getTiddler(title);\n\t\tif(!tiddler) {\n\t\t\ttiddler = new $tw.Tiddler({title: title, text: \"\", type: \"text/vnd.tiddlywiki\"});\n\t\t}\n\t\tvar contentTypeInfo = $tw.config.contentTypeInfo[tiddler.fields.type] || $tw.config.contentTypeInfo[\"text/vnd.tiddlywiki\"],\n\t\t\tsearchFields;\n\t\t// Get the list of fields we're searching\n\t\tif(options.excludeField) {\n\t\t\tsearchFields = Object.keys(tiddler.fields);\n\t\t\t$tw.utils.each(fields,function(fieldName) {\n\t\t\t\tvar p = searchFields.indexOf(fieldName);\n\t\t\t\tif(p !== -1) {\n\t\t\t\t\tsearchFields.splice(p,1);\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tsearchFields = fields;\n\t\t}\n\t\tfor(var fieldIndex=0; notYetFound.length>0 && fieldIndex<searchFields.length; fieldIndex++) {\n\t\t\t// Don't search the text field if the content type is binary\n\t\t\tvar fieldName = searchFields[fieldIndex];\n\t\t\tif(fieldName === \"text\" && contentTypeInfo.encoding !== \"utf8\") {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tvar str = tiddler.fields[fieldName],\n\t\t\t\tt;\n\t\t\tif(str) {\n\t\t\t\tif($tw.utils.isArray(str)) {\n\t\t\t\t\t// If the field value is an array, test each regexp against each field array entry and fail if each regexp doesn't match at least one field array entry\n\t\t\t\t\tfor(var s=0; s<str.length; s++) {\n\t\t\t\t\t\tfor(t=0; t<notYetFound.length;) {\n\t\t\t\t\t\t\tif(notYetFound[t].test(str[s])) {\n\t\t\t\t\t\t\t\tnotYetFound.splice(t, 1);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tt++;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// If the field isn't an array, force it to a string and test each regexp against it and fail if any do not match\n\t\t\t\t\tstr = tiddler.getFieldString(fieldName);\n\t\t\t\t\tfor(t=0; t<notYetFound.length;) {\n\t\t\t\t\t\tif(notYetFound[t].test(str)) {\n\t\t\t\t\t\t\tnotYetFound.splice(t, 1);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tt++;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\treturn notYetFound.length == 0;\n\t};\n\t// Loop through all the tiddlers doing the search\n\tvar results = [],\n\t\tsource = options.source || this.each;\n\tsource(function(tiddler,title) {\n\t\tif(searchTiddler(title) !== options.invert) {\n\t\t\tresults.push(title);\n\t\t}\n\t});\n\t// Remove any of the results we have to exclude\n\tif(options.exclude) {\n\t\tfor(t=0; t<options.exclude.length; t++) {\n\t\t\tvar p = results.indexOf(options.exclude[t]);\n\t\t\tif(p !== -1) {\n\t\t\t\tresults.splice(p,1);\n\t\t\t}\n\t\t}\n\t}\n\treturn results;\n};\n\n/*\nTrigger a load for a tiddler if it is skinny. Returns the text, or undefined if the tiddler is missing, null if the tiddler is being lazily loaded.\n*/\nexports.getTiddlerText = function(title,defaultText) {\n\tvar tiddler = this.getTiddler(title);\n\t// Return undefined if the tiddler isn't found\n\tif(!tiddler) {\n\t\treturn defaultText;\n\t}\n\tif(tiddler.fields.text !== undefined) {\n\t\t// Just return the text if we've got it\n\t\treturn tiddler.fields.text;\n\t} else {\n\t\t// Tell any listeners about the need to lazily load this tiddler\n\t\tthis.dispatchEvent(\"lazyLoad\",title);\n\t\t// Indicate that the text is being loaded\n\t\treturn null;\n\t}\n};\n\n/*\nCheck whether the text of a tiddler matches a given value. By default, the comparison is case insensitive, and any spaces at either end of the tiddler text is trimmed\n*/\nexports.checkTiddlerText = function(title,targetText,options) {\n\toptions = options || {};\n\tvar text = this.getTiddlerText(title,\"\");\n\tif(!options.noTrim) {\n\t\ttext = text.trim();\n\t}\n\tif(!options.caseSensitive) {\n\t\ttext = text.toLowerCase();\n\t\ttargetText = targetText.toLowerCase();\n\t}\n\treturn text === targetText;\n}\n\n/*\nRead an array of browser File objects, invoking callback(tiddlerFieldsArray) once they're all read\n*/\nexports.readFiles = function(files,options) {\n\tvar callback;\n\tif(typeof options === \"function\") {\n\t\tcallback = options;\n\t\toptions = {};\n\t} else {\n\t\tcallback = options.callback;\n\t}\n\tvar result = [],\n\t\toutstanding = files.length,\n\t\treadFileCallback = function(tiddlerFieldsArray) {\n\t\t\tresult.push.apply(result,tiddlerFieldsArray);\n\t\t\tif(--outstanding === 0) {\n\t\t\t\tcallback(result);\n\t\t\t}\n\t\t};\n\tfor(var f=0; f<files.length; f++) {\n\t\tthis.readFile(files[f],$tw.utils.extend({},options,{callback: readFileCallback}));\n\t}\n\treturn files.length;\n};\n\n/*\nRead a browser File object, invoking callback(tiddlerFieldsArray) with an array of tiddler fields objects\n*/\nexports.readFile = function(file,options) {\n\tvar callback;\n\tif(typeof options === \"function\") {\n\t\tcallback = options;\n\t\toptions = {};\n\t} else {\n\t\tcallback = options.callback;\n\t}\n\t// Get the type, falling back to the filename extension\n\tvar self = this,\n\t\ttype = file.type;\n\tif(type === \"\" || !type) {\n\t\tvar dotPos = file.name.lastIndexOf(\".\");\n\t\tif(dotPos !== -1) {\n\t\t\tvar fileExtensionInfo = $tw.utils.getFileExtensionInfo(file.name.substr(dotPos));\n\t\t\tif(fileExtensionInfo) {\n\t\t\t\ttype = fileExtensionInfo.type;\n\t\t\t}\n\t\t}\n\t}\n\t// Figure out if we're reading a binary file\n\tvar contentTypeInfo = $tw.config.contentTypeInfo[type],\n\t\tisBinary = contentTypeInfo ? contentTypeInfo.encoding === \"base64\" : false;\n\t// Log some debugging information\n\tif($tw.log.IMPORT) {\n\t\tconsole.log(\"Importing file '\" + file.name + \"', type: '\" + type + \"', isBinary: \" + isBinary);\n\t}\n\t// Give the hook a chance to process the drag\n\tif($tw.hooks.invokeHook(\"th-importing-file\",{\n\t\tfile: file,\n\t\ttype: type,\n\t\tisBinary: isBinary,\n\t\tcallback: callback\n\t}) !== true) {\n\t\tthis.readFileContent(file,type,isBinary,options.deserializer,callback);\n\t}\n};\n\n/*\nLower level utility to read the content of a browser File object, invoking callback(tiddlerFieldsArray) with an array of tiddler fields objects\n*/\nexports.readFileContent = function(file,type,isBinary,deserializer,callback) {\n\tvar self = this;\n\t// Create the FileReader\n\tvar reader = new FileReader();\n\t// Onload\n\treader.onload = function(event) {\n\t\tvar text = event.target.result,\n\t\t\ttiddlerFields = {title: file.name || \"Untitled\", type: type};\n\t\tif(isBinary) {\n\t\t\tvar commaPos = text.indexOf(\",\");\n\t\t\tif(commaPos !== -1) {\n\t\t\t\ttext = text.substr(commaPos + 1);\n\t\t\t}\n\t\t}\n\t\t// Check whether this is an encrypted TiddlyWiki file\n\t\tvar encryptedJson = $tw.utils.extractEncryptedStoreArea(text);\n\t\tif(encryptedJson) {\n\t\t\t// If so, attempt to decrypt it with the current password\n\t\t\t$tw.utils.decryptStoreAreaInteractive(encryptedJson,function(tiddlers) {\n\t\t\t\tcallback(tiddlers);\n\t\t\t});\n\t\t} else {\n\t\t\t// Otherwise, just try to deserialise any tiddlers in the file\n\t\t\tcallback(self.deserializeTiddlers(type,text,tiddlerFields,{deserializer: deserializer}));\n\t\t}\n\t};\n\t// Kick off the read\n\tif(isBinary) {\n\t\treader.readAsDataURL(file);\n\t} else {\n\t\treader.readAsText(file);\n\t}\n};\n\n/*\nFind any existing draft of a specified tiddler\n*/\nexports.findDraft = function(targetTitle) {\n\tvar draftTitle = undefined;\n\tthis.forEachTiddler({includeSystem: true},function(title,tiddler) {\n\t\tif(tiddler.fields[\"draft.title\"] && tiddler.fields[\"draft.of\"] === targetTitle) {\n\t\t\tdraftTitle = title;\n\t\t}\n\t});\n\treturn draftTitle;\n}\n\n/*\nCheck whether the specified draft tiddler has been modified.\nIf the original tiddler doesn't exist, create a vanilla tiddler variable,\nto check if additional fields have been added.\n*/\nexports.isDraftModified = function(title) {\n\tvar tiddler = this.getTiddler(title);\n\tif(!tiddler.isDraft()) {\n\t\treturn false;\n\t}\n\tvar ignoredFields = [\"created\", \"modified\", \"title\", \"draft.title\", \"draft.of\"],\n\t\torigTiddler = this.getTiddler(tiddler.fields[\"draft.of\"]) || new $tw.Tiddler({text:\"\", tags:[]}),\n\t\ttitleModified = tiddler.fields[\"draft.title\"] !== tiddler.fields[\"draft.of\"];\n\treturn titleModified || !tiddler.isEqual(origTiddler,ignoredFields);\n};\n\n/*\nAdd a new record to the top of the history stack\ntitle: a title string or an array of title strings\nfromPageRect: page coordinates of the origin of the navigation\nhistoryTitle: title of history tiddler (defaults to $:/HistoryList)\n*/\nexports.addToHistory = function(title,fromPageRect,historyTitle) {\n\tvar story = new $tw.Story({wiki: this, historyTitle: historyTitle});\n\tstory.addToHistory(title,fromPageRect);\n};\n\n/*\nAdd a new tiddler to the story river\ntitle: a title string or an array of title strings\nfromTitle: the title of the tiddler from which the navigation originated\nstoryTitle: title of story tiddler (defaults to $:/StoryList)\noptions: see story.js\n*/\nexports.addToStory = function(title,fromTitle,storyTitle,options) {\n\tvar story = new $tw.Story({wiki: this, storyTitle: storyTitle});\n\tstory.addToStory(title,fromTitle,options);\n};\n\n/*\nInvoke the available upgrader modules\ntitles: array of tiddler titles to be processed\ntiddlers: hashmap by title of tiddler fields of pending import tiddlers. These can be modified by the upgraders. An entry with no fields indicates a tiddler that was pending import has been suppressed. When entries are added to the pending import the tiddlers hashmap may have entries that are not present in the titles array\nReturns a hashmap of messages keyed by tiddler title.\n*/\nexports.invokeUpgraders = function(titles,tiddlers) {\n\t// Collect up the available upgrader modules\n\tvar self = this;\n\tif(!this.upgraderModules) {\n\t\tthis.upgraderModules = [];\n\t\t$tw.modules.forEachModuleOfType(\"upgrader\",function(title,module) {\n\t\t\tif(module.upgrade) {\n\t\t\t\tself.upgraderModules.push(module);\n\t\t\t}\n\t\t});\n\t}\n\t// Invoke each upgrader in turn\n\tvar messages = {};\n\tfor(var t=0; t<this.upgraderModules.length; t++) {\n\t\tvar upgrader = this.upgraderModules[t],\n\t\t\tupgraderMessages = upgrader.upgrade(this,titles,tiddlers);\n\t\t$tw.utils.extend(messages,upgraderMessages);\n\t}\n\treturn messages;\n};\n\n})();\n\n",
"type": "application/javascript",
"module-type": "wikimethod"
},
"$:/palettes/Blanca": {
"title": "$:/palettes/Blanca",
"name": "Blanca",
"description": "A clean white palette to let you focus",
"tags": "$:/tags/Palette",
"type": "application/x-tiddler-dictionary",
"text": "alert-background: #ffe476\nalert-border: #b99e2f\nalert-highlight: #881122\nalert-muted-foreground: #b99e2f\nbackground: #ffffff\nblockquote-bar: <<colour muted-foreground>>\nbutton-background:\nbutton-foreground:\nbutton-border:\ncode-background: #f7f7f9\ncode-border: #e1e1e8\ncode-foreground: #dd1144\ndirty-indicator: #ff0000\ndownload-background: #66cccc\ndownload-foreground: <<colour background>>\ndragger-background: <<colour foreground>>\ndragger-foreground: <<colour background>>\ndropdown-background: <<colour background>>\ndropdown-border: <<colour muted-foreground>>\ndropdown-tab-background-selected: #fff\ndropdown-tab-background: #ececec\ndropzone-background: rgba(0,200,0,0.7)\nexternal-link-background-hover: inherit\nexternal-link-background-visited: inherit\nexternal-link-background: inherit\nexternal-link-foreground-hover: inherit\nexternal-link-foreground-visited: #0000aa\nexternal-link-foreground: #0000ee\nforeground: #333333\nmessage-background: #ecf2ff\nmessage-border: #cfd6e6\nmessage-foreground: #547599\nmodal-backdrop: <<colour foreground>>\nmodal-background: <<colour background>>\nmodal-border: #999999\nmodal-footer-background: #f5f5f5\nmodal-footer-border: #dddddd\nmodal-header-border: #eeeeee\nmuted-foreground: #999999\nnotification-background: #ffffdd\nnotification-border: #999999\npage-background: #ffffff\npre-background: #f5f5f5\npre-border: #cccccc\nprimary: #7897f3\nselect-tag-background:\nselect-tag-foreground:\nsidebar-button-foreground: <<colour foreground>>\nsidebar-controls-foreground-hover: #000000\nsidebar-controls-foreground: #ccc\nsidebar-foreground-shadow: rgba(255,255,255, 0.8)\nsidebar-foreground: #acacac\nsidebar-muted-foreground-hover: #444444\nsidebar-muted-foreground: #c0c0c0\nsidebar-tab-background-selected: #ffffff\nsidebar-tab-background: <<colour tab-background>>\nsidebar-tab-border-selected: <<colour tab-border-selected>>\nsidebar-tab-border: <<colour tab-border>>\nsidebar-tab-divider: <<colour tab-divider>>\nsidebar-tab-foreground-selected: \nsidebar-tab-foreground: <<colour tab-foreground>>\nsidebar-tiddler-link-foreground-hover: #444444\nsidebar-tiddler-link-foreground: #7897f3\nsite-title-foreground: <<colour tiddler-title-foreground>>\nstatic-alert-foreground: #aaaaaa\ntab-background-selected: #ffffff\ntab-background: #eeeeee\ntab-border-selected: #cccccc\ntab-border: #cccccc\ntab-divider: #d8d8d8\ntab-foreground-selected: <<colour tab-foreground>>\ntab-foreground: #666666\ntable-border: #dddddd\ntable-footer-background: #a8a8a8\ntable-header-background: #f0f0f0\ntag-background: #ffeedd\ntag-foreground: #000\ntiddler-background: <<colour background>>\ntiddler-border: #eee\ntiddler-controls-foreground-hover: #888888\ntiddler-controls-foreground-selected: #444444\ntiddler-controls-foreground: #cccccc\ntiddler-editor-background: #f8f8f8\ntiddler-editor-border-image: #ffffff\ntiddler-editor-border: #cccccc\ntiddler-editor-fields-even: #e0e8e0\ntiddler-editor-fields-odd: #f0f4f0\ntiddler-info-background: #f8f8f8\ntiddler-info-border: #dddddd\ntiddler-info-tab-background: #f8f8f8\ntiddler-link-background: <<colour background>>\ntiddler-link-foreground: <<colour primary>>\ntiddler-subtitle-foreground: #c0c0c0\ntiddler-title-foreground: #ff9900\ntoolbar-new-button:\ntoolbar-options-button:\ntoolbar-save-button:\ntoolbar-info-button:\ntoolbar-edit-button:\ntoolbar-close-button:\ntoolbar-delete-button:\ntoolbar-cancel-button:\ntoolbar-done-button:\nuntagged-background: #999999\nvery-muted-foreground: #888888\n"
},
"$:/palettes/Blue": {
"title": "$:/palettes/Blue",
"name": "Blue",
"description": "A blue theme",
"tags": "$:/tags/Palette",
"type": "application/x-tiddler-dictionary",
"text": "alert-background: #ffe476\nalert-border: #b99e2f\nalert-highlight: #881122\nalert-muted-foreground: #b99e2f\nbackground: #fff\nblockquote-bar: <<colour muted-foreground>>\nbutton-background:\nbutton-foreground:\nbutton-border:\ncode-background: #f7f7f9\ncode-border: #e1e1e8\ncode-foreground: #dd1144\ndirty-indicator: #ff0000\ndownload-background: #34c734\ndownload-foreground: <<colour foreground>>\ndragger-background: <<colour foreground>>\ndragger-foreground: <<colour background>>\ndropdown-background: <<colour background>>\ndropdown-border: <<colour muted-foreground>>\ndropdown-tab-background-selected: #fff\ndropdown-tab-background: #ececec\ndropzone-background: rgba(0,200,0,0.7)\nexternal-link-background-hover: inherit\nexternal-link-background-visited: inherit\nexternal-link-background: inherit\nexternal-link-foreground-hover: inherit\nexternal-link-foreground-visited: #0000aa\nexternal-link-foreground: #0000ee\nforeground: #333353\nmessage-background: #ecf2ff\nmessage-border: #cfd6e6\nmessage-foreground: #547599\nmodal-backdrop: <<colour foreground>>\nmodal-background: <<colour background>>\nmodal-border: #999999\nmodal-footer-background: #f5f5f5\nmodal-footer-border: #dddddd\nmodal-header-border: #eeeeee\nmuted-foreground: #999999\nnotification-background: #ffffdd\nnotification-border: #999999\npage-background: #ddddff\npre-background: #f5f5f5\npre-border: #cccccc\nprimary: #5778d8\nselect-tag-background:\nselect-tag-foreground:\nsidebar-button-foreground: <<colour foreground>>\nsidebar-controls-foreground-hover: #000000\nsidebar-controls-foreground: #ffffff\nsidebar-foreground-shadow: rgba(255,255,255, 0.8)\nsidebar-foreground: #acacac\nsidebar-muted-foreground-hover: #444444\nsidebar-muted-foreground: #c0c0c0\nsidebar-tab-background-selected: <<colour page-background>>\nsidebar-tab-background: <<colour tab-background>>\nsidebar-tab-border-selected: <<colour tab-border-selected>>\nsidebar-tab-border: <<colour tab-border>>\nsidebar-tab-divider: <<colour tab-divider>>\nsidebar-tab-foreground-selected: \nsidebar-tab-foreground: <<colour tab-foreground>>\nsidebar-tiddler-link-foreground-hover: #444444\nsidebar-tiddler-link-foreground: #5959c0\nsite-title-foreground: <<colour tiddler-title-foreground>>\nstatic-alert-foreground: #aaaaaa\ntab-background-selected: <<colour background>>\ntab-background: #ccccdd\ntab-border-selected: #ccccdd\ntab-border: #cccccc\ntab-divider: #d8d8d8\ntab-foreground-selected: <<colour tab-foreground>>\ntab-foreground: #666666\ntable-border: #dddddd\ntable-footer-background: #a8a8a8\ntable-header-background: #f0f0f0\ntag-background: #eeeeff\ntag-foreground: #000\ntiddler-background: <<colour background>>\ntiddler-border: <<colour background>>\ntiddler-controls-foreground-hover: #666666\ntiddler-controls-foreground-selected: #444444\ntiddler-controls-foreground: #cccccc\ntiddler-editor-background: #f8f8f8\ntiddler-editor-border-image: #ffffff\ntiddler-editor-border: #cccccc\ntiddler-editor-fields-even: #e0e8e0\ntiddler-editor-fields-odd: #f0f4f0\ntiddler-info-background: #ffffff\ntiddler-info-border: #dddddd\ntiddler-info-tab-background: #ffffff\ntiddler-link-background: <<colour background>>\ntiddler-link-foreground: <<colour primary>>\ntiddler-subtitle-foreground: #c0c0c0\ntiddler-title-foreground: #5959c0\ntoolbar-new-button: #5eb95e\ntoolbar-options-button: rgb(128, 88, 165)\ntoolbar-save-button: #0e90d2\ntoolbar-info-button: #0e90d2\ntoolbar-edit-button: rgb(243, 123, 29)\ntoolbar-close-button: #dd514c\ntoolbar-delete-button: #dd514c\ntoolbar-cancel-button: rgb(243, 123, 29)\ntoolbar-done-button: #5eb95e\nuntagged-background: #999999\nvery-muted-foreground: #888888\n"
},
"$:/palettes/Muted": {
"title": "$:/palettes/Muted",
"name": "Muted",
"description": "Bright tiddlers on a muted background",
"tags": "$:/tags/Palette",
"type": "application/x-tiddler-dictionary",
"text": "alert-background: #ffe476\nalert-border: #b99e2f\nalert-highlight: #881122\nalert-muted-foreground: #b99e2f\nbackground: #ffffff\nblockquote-bar: <<colour muted-foreground>>\nbutton-background:\nbutton-foreground:\nbutton-border:\ncode-background: #f7f7f9\ncode-border: #e1e1e8\ncode-foreground: #dd1144\ndirty-indicator: #ff0000\ndownload-background: #34c734\ndownload-foreground: <<colour background>>\ndragger-background: <<colour foreground>>\ndragger-foreground: <<colour background>>\ndropdown-background: <<colour background>>\ndropdown-border: <<colour muted-foreground>>\ndropdown-tab-background-selected: #fff\ndropdown-tab-background: #ececec\ndropzone-background: rgba(0,200,0,0.7)\nexternal-link-background-hover: inherit\nexternal-link-background-visited: inherit\nexternal-link-background: inherit\nexternal-link-foreground-hover: inherit\nexternal-link-foreground-visited: #0000aa\nexternal-link-foreground: #0000ee\nforeground: #333333\nmessage-background: #ecf2ff\nmessage-border: #cfd6e6\nmessage-foreground: #547599\nmodal-backdrop: <<colour foreground>>\nmodal-background: <<colour background>>\nmodal-border: #999999\nmodal-footer-background: #f5f5f5\nmodal-footer-border: #dddddd\nmodal-header-border: #eeeeee\nmuted-foreground: #bbb\nnotification-background: #ffffdd\nnotification-border: #999999\npage-background: #6f6f70\npre-background: #f5f5f5\npre-border: #cccccc\nprimary: #29a6ee\nselect-tag-background:\nselect-tag-foreground:\nsidebar-button-foreground: <<colour foreground>>\nsidebar-controls-foreground-hover: #000000\nsidebar-controls-foreground: #c2c1c2\nsidebar-foreground-shadow: rgba(255,255,255,0)\nsidebar-foreground: #d3d2d4\nsidebar-muted-foreground-hover: #444444\nsidebar-muted-foreground: #c0c0c0\nsidebar-tab-background-selected: #6f6f70\nsidebar-tab-background: #666667\nsidebar-tab-border-selected: #999\nsidebar-tab-border: #515151\nsidebar-tab-divider: #999\nsidebar-tab-foreground-selected: \nsidebar-tab-foreground: #999\nsidebar-tiddler-link-foreground-hover: #444444\nsidebar-tiddler-link-foreground: #d1d0d2\nsite-title-foreground: <<colour tiddler-title-foreground>>\nstatic-alert-foreground: #aaaaaa\ntab-background-selected: #ffffff\ntab-background: #d8d8d8\ntab-border-selected: #d8d8d8\ntab-border: #cccccc\ntab-divider: #d8d8d8\ntab-foreground-selected: <<colour tab-foreground>>\ntab-foreground: #666666\ntable-border: #dddddd\ntable-footer-background: #a8a8a8\ntable-header-background: #f0f0f0\ntag-background: #d5ad34\ntag-foreground: #ffffff\ntiddler-background: <<colour background>>\ntiddler-border: <<colour background>>\ntiddler-controls-foreground-hover: #888888\ntiddler-controls-foreground-selected: #444444\ntiddler-controls-foreground: #cccccc\ntiddler-editor-background: #f8f8f8\ntiddler-editor-border-image: #ffffff\ntiddler-editor-border: #cccccc\ntiddler-editor-fields-even: #e0e8e0\ntiddler-editor-fields-odd: #f0f4f0\ntiddler-info-background: #f8f8f8\ntiddler-info-border: #dddddd\ntiddler-info-tab-background: #f8f8f8\ntiddler-link-background: <<colour background>>\ntiddler-link-foreground: <<colour primary>>\ntiddler-subtitle-foreground: #c0c0c0\ntiddler-title-foreground: #182955\ntoolbar-new-button: \ntoolbar-options-button: \ntoolbar-save-button: \ntoolbar-info-button: \ntoolbar-edit-button: \ntoolbar-close-button: \ntoolbar-delete-button: \ntoolbar-cancel-button: \ntoolbar-done-button: \nuntagged-background: #999999\nvery-muted-foreground: #888888\n"
},
"$:/palettes/ContrastLight": {
"title": "$:/palettes/ContrastLight",
"name": "Contrast (Light)",
"description": "High contrast and unambiguous (light version)",
"tags": "$:/tags/Palette",
"type": "application/x-tiddler-dictionary",
"text": "alert-background: #f00\nalert-border: <<colour background>>\nalert-highlight: <<colour foreground>>\nalert-muted-foreground: #800\nbackground: #fff\nblockquote-bar: <<colour muted-foreground>>\nbutton-background: <<colour background>>\nbutton-foreground: <<colour foreground>>\nbutton-border: <<colour foreground>>\ncode-background: <<colour background>>\ncode-border: <<colour foreground>>\ncode-foreground: <<colour foreground>>\ndirty-indicator: #f00\ndownload-background: #080\ndownload-foreground: <<colour background>>\ndragger-background: <<colour foreground>>\ndragger-foreground: <<colour background>>\ndropdown-background: <<colour background>>\ndropdown-border: <<colour muted-foreground>>\ndropdown-tab-background-selected: <<colour foreground>>\ndropdown-tab-background: <<colour foreground>>\ndropzone-background: rgba(0,200,0,0.7)\nexternal-link-background-hover: inherit\nexternal-link-background-visited: inherit\nexternal-link-background: inherit\nexternal-link-foreground-hover: inherit\nexternal-link-foreground-visited: #00a\nexternal-link-foreground: #00e\nforeground: #000\nmessage-background: <<colour foreground>>\nmessage-border: <<colour background>>\nmessage-foreground: <<colour background>>\nmodal-backdrop: <<colour foreground>>\nmodal-background: <<colour background>>\nmodal-border: <<colour foreground>>\nmodal-footer-background: <<colour background>>\nmodal-footer-border: <<colour foreground>>\nmodal-header-border: <<colour foreground>>\nmuted-foreground: <<colour foreground>>\nnotification-background: <<colour background>>\nnotification-border: <<colour foreground>>\npage-background: <<colour background>>\npre-background: <<colour background>>\npre-border: <<colour foreground>>\nprimary: #00f\nselect-tag-background:\nselect-tag-foreground:\nsidebar-button-foreground: <<colour foreground>>\nsidebar-controls-foreground-hover: <<colour background>>\nsidebar-controls-foreground: <<colour foreground>>\nsidebar-foreground-shadow: rgba(0,0,0, 0)\nsidebar-foreground: <<colour foreground>>\nsidebar-muted-foreground-hover: #444444\nsidebar-muted-foreground: <<colour foreground>>\nsidebar-tab-background-selected: <<colour background>>\nsidebar-tab-background: <<colour tab-background>>\nsidebar-tab-border-selected: <<colour tab-border-selected>>\nsidebar-tab-border: <<colour tab-border>>\nsidebar-tab-divider: <<colour tab-divider>>\nsidebar-tab-foreground-selected: <<colour foreground>>\nsidebar-tab-foreground: <<colour tab-foreground>>\nsidebar-tiddler-link-foreground-hover: <<colour foreground>>\nsidebar-tiddler-link-foreground: <<colour primary>>\nsite-title-foreground: <<colour tiddler-title-foreground>>\nstatic-alert-foreground: #aaaaaa\ntab-background-selected: <<colour background>>\ntab-background: <<colour foreground>>\ntab-border-selected: <<colour foreground>>\ntab-border: <<colour foreground>>\ntab-divider: <<colour foreground>>\ntab-foreground-selected: <<colour foreground>>\ntab-foreground: <<colour background>>\ntable-border: #dddddd\ntable-footer-background: #a8a8a8\ntable-header-background: #f0f0f0\ntag-background: #000\ntag-foreground: #fff\ntiddler-background: <<colour background>>\ntiddler-border: <<colour foreground>>\ntiddler-controls-foreground-hover: #ddd\ntiddler-controls-foreground-selected: #fdd\ntiddler-controls-foreground: <<colour foreground>>\ntiddler-editor-background: <<colour background>>\ntiddler-editor-border-image: <<colour foreground>>\ntiddler-editor-border: #cccccc\ntiddler-editor-fields-even: <<colour background>>\ntiddler-editor-fields-odd: <<colour background>>\ntiddler-info-background: <<colour background>>\ntiddler-info-border: <<colour foreground>>\ntiddler-info-tab-background: <<colour background>>\ntiddler-link-background: <<colour background>>\ntiddler-link-foreground: <<colour primary>>\ntiddler-subtitle-foreground: <<colour foreground>>\ntiddler-title-foreground: <<colour foreground>>\ntoolbar-new-button: \ntoolbar-options-button: \ntoolbar-save-button: \ntoolbar-info-button: \ntoolbar-edit-button: \ntoolbar-close-button: \ntoolbar-delete-button: \ntoolbar-cancel-button: \ntoolbar-done-button: \nuntagged-background: <<colour foreground>>\nvery-muted-foreground: #888888\n"
},
"$:/palettes/ContrastDark": {
"title": "$:/palettes/ContrastDark",
"name": "Contrast (Dark)",
"description": "High contrast and unambiguous (dark version)",
"tags": "$:/tags/Palette",
"type": "application/x-tiddler-dictionary",
"text": "alert-background: #f00\nalert-border: <<colour background>>\nalert-highlight: <<colour foreground>>\nalert-muted-foreground: #800\nbackground: #000\nblockquote-bar: <<colour muted-foreground>>\nbutton-background: <<colour background>>\nbutton-foreground: <<colour foreground>>\nbutton-border: <<colour foreground>>\ncode-background: <<colour background>>\ncode-border: <<colour foreground>>\ncode-foreground: <<colour foreground>>\ndirty-indicator: #f00\ndownload-background: #080\ndownload-foreground: <<colour background>>\ndragger-background: <<colour foreground>>\ndragger-foreground: <<colour background>>\ndropdown-background: <<colour background>>\ndropdown-border: <<colour muted-foreground>>\ndropdown-tab-background-selected: <<colour foreground>>\ndropdown-tab-background: <<colour foreground>>\ndropzone-background: rgba(0,200,0,0.7)\nexternal-link-background-hover: inherit\nexternal-link-background-visited: inherit\nexternal-link-background: inherit\nexternal-link-foreground-hover: inherit\nexternal-link-foreground-visited: #00a\nexternal-link-foreground: #00e\nforeground: #fff\nmessage-background: <<colour foreground>>\nmessage-border: <<colour background>>\nmessage-foreground: <<colour background>>\nmodal-backdrop: <<colour foreground>>\nmodal-background: <<colour background>>\nmodal-border: <<colour foreground>>\nmodal-footer-background: <<colour background>>\nmodal-footer-border: <<colour foreground>>\nmodal-header-border: <<colour foreground>>\nmuted-foreground: <<colour foreground>>\nnotification-background: <<colour background>>\nnotification-border: <<colour foreground>>\npage-background: <<colour background>>\npre-background: <<colour background>>\npre-border: <<colour foreground>>\nprimary: #00f\nselect-tag-background:\nselect-tag-foreground:\nsidebar-button-foreground: <<colour foreground>>\nsidebar-controls-foreground-hover: <<colour background>>\nsidebar-controls-foreground: <<colour foreground>>\nsidebar-foreground-shadow: rgba(0,0,0, 0)\nsidebar-foreground: <<colour foreground>>\nsidebar-muted-foreground-hover: #444444\nsidebar-muted-foreground: <<colour foreground>>\nsidebar-tab-background-selected: <<colour background>>\nsidebar-tab-background: <<colour tab-background>>\nsidebar-tab-border-selected: <<colour tab-border-selected>>\nsidebar-tab-border: <<colour tab-border>>\nsidebar-tab-divider: <<colour tab-divider>>\nsidebar-tab-foreground-selected: <<colour foreground>>\nsidebar-tab-foreground: <<colour tab-foreground>>\nsidebar-tiddler-link-foreground-hover: <<colour foreground>>\nsidebar-tiddler-link-foreground: <<colour primary>>\nsite-title-foreground: <<colour tiddler-title-foreground>>\nstatic-alert-foreground: #aaaaaa\ntab-background-selected: <<colour background>>\ntab-background: <<colour foreground>>\ntab-border-selected: <<colour foreground>>\ntab-border: <<colour foreground>>\ntab-divider: <<colour foreground>>\ntab-foreground-selected: <<colour foreground>>\ntab-foreground: <<colour background>>\ntable-border: #dddddd\ntable-footer-background: #a8a8a8\ntable-header-background: #f0f0f0\ntag-background: #fff\ntag-foreground: #000\ntiddler-background: <<colour background>>\ntiddler-border: <<colour foreground>>\ntiddler-controls-foreground-hover: #ddd\ntiddler-controls-foreground-selected: #fdd\ntiddler-controls-foreground: <<colour foreground>>\ntiddler-editor-background: <<colour background>>\ntiddler-editor-border-image: <<colour foreground>>\ntiddler-editor-border: #cccccc\ntiddler-editor-fields-even: <<colour background>>\ntiddler-editor-fields-odd: <<colour background>>\ntiddler-info-background: <<colour background>>\ntiddler-info-border: <<colour foreground>>\ntiddler-info-tab-background: <<colour background>>\ntiddler-link-background: <<colour background>>\ntiddler-link-foreground: <<colour primary>>\ntiddler-subtitle-foreground: <<colour foreground>>\ntiddler-title-foreground: <<colour foreground>>\ntoolbar-new-button: \ntoolbar-options-button: \ntoolbar-save-button: \ntoolbar-info-button: \ntoolbar-edit-button: \ntoolbar-close-button: \ntoolbar-delete-button: \ntoolbar-cancel-button: \ntoolbar-done-button: \nuntagged-background: <<colour foreground>>\nvery-muted-foreground: #888888\n"
},
"$:/palettes/DarkPhotos": {
"title": "$:/palettes/DarkPhotos",
"created": "20150402111612188",
"description": "Good with dark photo backgrounds",
"modified": "20150402112344080",
"name": "DarkPhotos",
"tags": "$:/tags/Palette",
"type": "application/x-tiddler-dictionary",
"text": "alert-background: #ffe476\nalert-border: #b99e2f\nalert-highlight: #881122\nalert-muted-foreground: #b99e2f\nbackground: #ffffff\nblockquote-bar: <<colour muted-foreground>>\nbutton-background: \nbutton-foreground: \nbutton-border: \ncode-background: #f7f7f9\ncode-border: #e1e1e8\ncode-foreground: #dd1144\ndirty-indicator: #ff0000\ndownload-background: #34c734\ndownload-foreground: <<colour background>>\ndragger-background: <<colour foreground>>\ndragger-foreground: <<colour background>>\ndropdown-background: <<colour background>>\ndropdown-border: <<colour muted-foreground>>\ndropdown-tab-background-selected: #fff\ndropdown-tab-background: #ececec\ndropzone-background: rgba(0,200,0,0.7)\nexternal-link-background-hover: inherit\nexternal-link-background-visited: inherit\nexternal-link-background: inherit\nexternal-link-foreground-hover: inherit\nexternal-link-foreground-visited: #0000aa\nexternal-link-foreground: #0000ee\nforeground: #333333\nmessage-background: #ecf2ff\nmessage-border: #cfd6e6\nmessage-foreground: #547599\nmodal-backdrop: <<colour foreground>>\nmodal-background: <<colour background>>\nmodal-border: #999999\nmodal-footer-background: #f5f5f5\nmodal-footer-border: #dddddd\nmodal-header-border: #eeeeee\nmuted-foreground: #ddd\nnotification-background: #ffffdd\nnotification-border: #999999\npage-background: #336438\npre-background: #f5f5f5\npre-border: #cccccc\nprimary: #5778d8\nselect-tag-background:\nselect-tag-foreground:\nsidebar-button-foreground: <<colour foreground>>\nsidebar-controls-foreground-hover: #ccf\nsidebar-controls-foreground: #fff\nsidebar-foreground-shadow: rgba(0,0,0, 0.5)\nsidebar-foreground: #fff\nsidebar-muted-foreground-hover: #444444\nsidebar-muted-foreground: #eee\nsidebar-tab-background-selected: rgba(255,255,255, 0.8)\nsidebar-tab-background: rgba(255,255,255, 0.4)\nsidebar-tab-border-selected: <<colour tab-border-selected>>\nsidebar-tab-border: <<colour tab-border>>\nsidebar-tab-divider: rgba(255,255,255, 0.2)\nsidebar-tab-foreground-selected: \nsidebar-tab-foreground: <<colour tab-foreground>>\nsidebar-tiddler-link-foreground-hover: #aaf\nsidebar-tiddler-link-foreground: #ddf\nsite-title-foreground: #fff\nstatic-alert-foreground: #aaaaaa\ntab-background-selected: #ffffff\ntab-background: #d8d8d8\ntab-border-selected: #d8d8d8\ntab-border: #cccccc\ntab-divider: #d8d8d8\ntab-foreground-selected: <<colour tab-foreground>>\ntab-foreground: #666666\ntable-border: #dddddd\ntable-footer-background: #a8a8a8\ntable-header-background: #f0f0f0\ntag-background: #ec6\ntag-foreground: #ffffff\ntiddler-background: <<colour background>>\ntiddler-border: <<colour background>>\ntiddler-controls-foreground-hover: #888888\ntiddler-controls-foreground-selected: #444444\ntiddler-controls-foreground: #cccccc\ntiddler-editor-background: #f8f8f8\ntiddler-editor-border-image: #ffffff\ntiddler-editor-border: #cccccc\ntiddler-editor-fields-even: #e0e8e0\ntiddler-editor-fields-odd: #f0f4f0\ntiddler-info-background: #f8f8f8\ntiddler-info-border: #dddddd\ntiddler-info-tab-background: #f8f8f8\ntiddler-link-background: <<colour background>>\ntiddler-link-foreground: <<colour primary>>\ntiddler-subtitle-foreground: #c0c0c0\ntiddler-title-foreground: #182955\ntoolbar-new-button: \ntoolbar-options-button: \ntoolbar-save-button: \ntoolbar-info-button: \ntoolbar-edit-button: \ntoolbar-close-button: \ntoolbar-delete-button: \ntoolbar-cancel-button: \ntoolbar-done-button: \nuntagged-background: #999999\nvery-muted-foreground: #888888\n"
},
"$:/palettes/Rocker": {
"title": "$:/palettes/Rocker",
"name": "Rocker",
"description": "A dark theme",
"tags": "$:/tags/Palette",
"type": "application/x-tiddler-dictionary",
"text": "alert-background: #ffe476\nalert-border: #b99e2f\nalert-highlight: #881122\nalert-muted-foreground: #b99e2f\nbackground: #ffffff\nblockquote-bar: <<colour muted-foreground>>\nbutton-background:\nbutton-foreground:\nbutton-border:\ncode-background: #f7f7f9\ncode-border: #e1e1e8\ncode-foreground: #dd1144\ndirty-indicator: #ff0000\ndownload-background: #34c734\ndownload-foreground: <<colour background>>\ndragger-background: <<colour foreground>>\ndragger-foreground: <<colour background>>\ndropdown-background: <<colour background>>\ndropdown-border: <<colour muted-foreground>>\ndropdown-tab-background-selected: #fff\ndropdown-tab-background: #ececec\ndropzone-background: rgba(0,200,0,0.7)\nexternal-link-background-hover: inherit\nexternal-link-background-visited: inherit\nexternal-link-background: inherit\nexternal-link-foreground-hover: inherit\nexternal-link-foreground-visited: #0000aa\nexternal-link-foreground: #0000ee\nforeground: #333333\nmessage-background: #ecf2ff\nmessage-border: #cfd6e6\nmessage-foreground: #547599\nmodal-backdrop: <<colour foreground>>\nmodal-background: <<colour background>>\nmodal-border: #999999\nmodal-footer-background: #f5f5f5\nmodal-footer-border: #dddddd\nmodal-header-border: #eeeeee\nmuted-foreground: #999999\nnotification-background: #ffffdd\nnotification-border: #999999\npage-background: #000\npre-background: #f5f5f5\npre-border: #cccccc\nprimary: #cc0000\nselect-tag-background:\nselect-tag-foreground:\nsidebar-button-foreground: <<colour foreground>>\nsidebar-controls-foreground-hover: #000000\nsidebar-controls-foreground: #ffffff\nsidebar-foreground-shadow: rgba(255,255,255, 0.0)\nsidebar-foreground: #acacac\nsidebar-muted-foreground-hover: #444444\nsidebar-muted-foreground: #c0c0c0\nsidebar-tab-background-selected: #000\nsidebar-tab-background: <<colour tab-background>>\nsidebar-tab-border-selected: <<colour tab-border-selected>>\nsidebar-tab-border: <<colour tab-border>>\nsidebar-tab-divider: <<colour tab-divider>>\nsidebar-tab-foreground-selected: \nsidebar-tab-foreground: <<colour tab-foreground>>\nsidebar-tiddler-link-foreground-hover: #ffbb99\nsidebar-tiddler-link-foreground: #cc0000\nsite-title-foreground: <<colour tiddler-title-foreground>>\nstatic-alert-foreground: #aaaaaa\ntab-background-selected: #ffffff\ntab-background: #d8d8d8\ntab-border-selected: #d8d8d8\ntab-border: #cccccc\ntab-divider: #d8d8d8\ntab-foreground-selected: <<colour tab-foreground>>\ntab-foreground: #666666\ntable-border: #dddddd\ntable-footer-background: #a8a8a8\ntable-header-background: #f0f0f0\ntag-background: #ffbb99\ntag-foreground: #000\ntiddler-background: <<colour background>>\ntiddler-border: <<colour background>>\ntiddler-controls-foreground-hover: #888888\ntiddler-controls-foreground-selected: #444444\ntiddler-controls-foreground: #cccccc\ntiddler-editor-background: #f8f8f8\ntiddler-editor-border-image: #ffffff\ntiddler-editor-border: #cccccc\ntiddler-editor-fields-even: #e0e8e0\ntiddler-editor-fields-odd: #f0f4f0\ntiddler-info-background: #f8f8f8\ntiddler-info-border: #dddddd\ntiddler-info-tab-background: #f8f8f8\ntiddler-link-background: <<colour background>>\ntiddler-link-foreground: <<colour primary>>\ntiddler-subtitle-foreground: #c0c0c0\ntiddler-title-foreground: #cc0000\ntoolbar-new-button:\ntoolbar-options-button:\ntoolbar-save-button:\ntoolbar-info-button:\ntoolbar-edit-button:\ntoolbar-close-button:\ntoolbar-delete-button:\ntoolbar-cancel-button:\ntoolbar-done-button:\nuntagged-background: #999999\nvery-muted-foreground: #888888\n"
},
"$:/palettes/SolarFlare": {
"title": "$:/palettes/SolarFlare",
"name": "Solar Flare",
"description": "Warm, relaxing earth colours",
"tags": "$:/tags/Palette",
"type": "application/x-tiddler-dictionary",
"text": ": Background Tones\n\nbase03: #002b36\nbase02: #073642\n\n: Content Tones\n\nbase01: #586e75\nbase00: #657b83\nbase0: #839496\nbase1: #93a1a1\n\n: Background Tones\n\nbase2: #eee8d5\nbase3: #fdf6e3\n\n: Accent Colors\n\nyellow: #b58900\norange: #cb4b16\nred: #dc322f\nmagenta: #d33682\nviolet: #6c71c4\nblue: #268bd2\ncyan: #2aa198\ngreen: #859900\n\n: Additional Tones (RA)\n\nbase10: #c0c4bb\nviolet-muted: #7c81b0\nblue-muted: #4e7baa\n\nyellow-hot: #ffcc44\norange-hot: #eb6d20\nred-hot: #ff2222\nblue-hot: #2298ee\ngreen-hot: #98ee22\n\n: Palette\n\n: Do not use colour macro for background and foreground\nbackground: #fdf6e3\n download-foreground: <<colour background>>\n dragger-foreground: <<colour background>>\n dropdown-background: <<colour background>>\n modal-background: <<colour background>>\n sidebar-foreground-shadow: <<colour background>>\n tiddler-background: <<colour background>>\n tiddler-border: <<colour background>>\n tiddler-link-background: <<colour background>>\n tab-background-selected: <<colour background>>\n dropdown-tab-background-selected: <<colour tab-background-selected>>\nforeground: #657b83\n dragger-background: <<colour foreground>>\n tab-foreground: <<colour foreground>>\n tab-foreground-selected: <<colour tab-foreground>>\n sidebar-tab-foreground-selected: <<colour tab-foreground-selected>>\n sidebar-tab-foreground: <<colour tab-foreground>>\n sidebar-button-foreground: <<colour foreground>>\n sidebar-controls-foreground: <<colour foreground>>\n sidebar-foreground: <<colour foreground>>\n: base03\n: base02\n: base01\n alert-muted-foreground: <<colour base01>>\n: base00\n code-foreground: <<colour base00>>\n message-foreground: <<colour base00>>\n tag-foreground: <<colour base00>>\n: base0\n sidebar-tiddler-link-foreground: <<colour base0>>\n: base1\n muted-foreground: <<colour base1>>\n blockquote-bar: <<colour muted-foreground>>\n dropdown-border: <<colour muted-foreground>>\n sidebar-muted-foreground: <<colour muted-foreground>>\n tiddler-title-foreground: <<colour muted-foreground>>\n site-title-foreground: <<colour tiddler-title-foreground>>\n: base2\n modal-footer-background: <<colour base2>>\n page-background: <<colour base2>>\n modal-backdrop: <<colour page-background>>\n notification-background: <<colour page-background>>\n code-background: <<colour page-background>>\n code-border: <<colour code-background>>\n pre-background: <<colour page-background>>\n pre-border: <<colour pre-background>>\n sidebar-tab-background-selected: <<colour page-background>>\n table-header-background: <<colour base2>>\n tag-background: <<colour base2>>\n tiddler-editor-background: <<colour base2>>\n tiddler-info-background: <<colour base2>>\n tiddler-info-tab-background: <<colour base2>>\n tab-background: <<colour base2>>\n dropdown-tab-background: <<colour tab-background>>\n: base3\n alert-background: <<colour base3>>\n message-background: <<colour base3>>\n: yellow\n: orange\n: red\n: magenta\n alert-highlight: <<colour magenta>>\n: violet\n external-link-foreground: <<colour violet>>\n: blue\n: cyan\n: green\n: base10\n tiddler-controls-foreground: <<colour base10>>\n: violet-muted\n external-link-foreground-visited: <<colour violet-muted>>\n: blue-muted\n primary: <<colour blue-muted>>\n download-background: <<colour primary>>\n tiddler-link-foreground: <<colour primary>>\n\nalert-border: #b99e2f\ndirty-indicator: #ff0000\ndropzone-background: rgba(0,200,0,0.7)\nexternal-link-background-hover: inherit\nexternal-link-background-visited: inherit\nexternal-link-background: inherit\nexternal-link-foreground-hover: inherit\nmessage-border: #cfd6e6\nmodal-border: #999999\nselect-tag-background:\nselect-tag-foreground:\nsidebar-controls-foreground-hover:\nsidebar-muted-foreground-hover:\nsidebar-tab-background: #ded8c5\nsidebar-tiddler-link-foreground-hover:\nstatic-alert-foreground: #aaaaaa\ntab-border: #cccccc\n modal-footer-border: <<colour tab-border>>\n modal-header-border: <<colour tab-border>>\n notification-border: <<colour tab-border>>\n sidebar-tab-border: <<colour tab-border>>\n tab-border-selected: <<colour tab-border>>\n sidebar-tab-border-selected: <<colour tab-border-selected>>\ntab-divider: #d8d8d8\n sidebar-tab-divider: <<colour tab-divider>>\ntable-border: #dddddd\ntable-footer-background: #a8a8a8\ntiddler-controls-foreground-hover: #888888\ntiddler-controls-foreground-selected: #444444\ntiddler-editor-border-image: #ffffff\ntiddler-editor-border: #cccccc\ntiddler-editor-fields-even: #e0e8e0\ntiddler-editor-fields-odd: #f0f4f0\ntiddler-info-border: #dddddd\ntiddler-subtitle-foreground: #c0c0c0\ntoolbar-new-button:\ntoolbar-options-button:\ntoolbar-save-button:\ntoolbar-info-button:\ntoolbar-edit-button:\ntoolbar-close-button:\ntoolbar-delete-button:\ntoolbar-cancel-button:\ntoolbar-done-button:\nuntagged-background: #999999\nvery-muted-foreground: #888888\n"
},
"$:/palettes/Vanilla": {
"title": "$:/palettes/Vanilla",
"name": "Vanilla",
"description": "Pale and unobtrusive",
"tags": "$:/tags/Palette",
"type": "application/x-tiddler-dictionary",
"text": "alert-background: #ffe476\nalert-border: #b99e2f\nalert-highlight: #881122\nalert-muted-foreground: #b99e2f\nbackground: #ffffff\nblockquote-bar: <<colour muted-foreground>>\nbutton-background:\nbutton-foreground:\nbutton-border:\ncode-background: #f7f7f9\ncode-border: #e1e1e8\ncode-foreground: #dd1144\ndiff-delete-background: #ffc9c9\ndiff-delete-foreground: <<colour foreground>>\ndiff-equal-background: \ndiff-equal-foreground: <<colour foreground>>\ndiff-insert-background: #aaefad\ndiff-insert-foreground: <<colour foreground>>\ndiff-invisible-background: \ndiff-invisible-foreground: <<colour muted-foreground>>\ndirty-indicator: #ff0000\ndownload-background: #34c734\ndownload-foreground: <<colour background>>\ndragger-background: <<colour foreground>>\ndragger-foreground: <<colour background>>\ndropdown-background: <<colour background>>\ndropdown-border: <<colour muted-foreground>>\ndropdown-tab-background-selected: #fff\ndropdown-tab-background: #ececec\ndropzone-background: rgba(0,200,0,0.7)\nexternal-link-background-hover: inherit\nexternal-link-background-visited: inherit\nexternal-link-background: inherit\nexternal-link-foreground-hover: inherit\nexternal-link-foreground-visited: #0000aa\nexternal-link-foreground: #0000ee\nforeground: #333333\nmessage-background: #ecf2ff\nmessage-border: #cfd6e6\nmessage-foreground: #547599\nmodal-backdrop: <<colour foreground>>\nmodal-background: <<colour background>>\nmodal-border: #999999\nmodal-footer-background: #f5f5f5\nmodal-footer-border: #dddddd\nmodal-header-border: #eeeeee\nmuted-foreground: #bbb\nnotification-background: #ffffdd\nnotification-border: #999999\npage-background: #f4f4f4\npre-background: #f5f5f5\npre-border: #cccccc\nprimary: #5778d8\nselect-tag-background:\nselect-tag-foreground:\nsidebar-button-foreground: <<colour foreground>>\nsidebar-controls-foreground-hover: #000000\nsidebar-controls-foreground: #aaaaaa\nsidebar-foreground-shadow: rgba(255,255,255, 0.8)\nsidebar-foreground: #acacac\nsidebar-muted-foreground-hover: #444444\nsidebar-muted-foreground: #c0c0c0\nsidebar-tab-background-selected: #f4f4f4\nsidebar-tab-background: #e0e0e0\nsidebar-tab-border-selected: <<colour tab-border-selected>>\nsidebar-tab-border: <<colour tab-border>>\nsidebar-tab-divider: #e4e4e4\nsidebar-tab-foreground-selected:\nsidebar-tab-foreground: <<colour tab-foreground>>\nsidebar-tiddler-link-foreground-hover: #444444\nsidebar-tiddler-link-foreground: #999999\nsite-title-foreground: <<colour tiddler-title-foreground>>\nstatic-alert-foreground: #aaaaaa\ntab-background-selected: #ffffff\ntab-background: #d8d8d8\ntab-border-selected: #d8d8d8\ntab-border: #cccccc\ntab-divider: #d8d8d8\ntab-foreground-selected: <<colour tab-foreground>>\ntab-foreground: #666666\ntable-border: #dddddd\ntable-footer-background: #a8a8a8\ntable-header-background: #f0f0f0\ntag-background: #ec6\ntag-foreground: #ffffff\ntiddler-background: <<colour background>>\ntiddler-border: <<colour background>>\ntiddler-controls-foreground-hover: #888888\ntiddler-controls-foreground-selected: #444444\ntiddler-controls-foreground: #cccccc\ntiddler-editor-background: #f8f8f8\ntiddler-editor-border-image: #ffffff\ntiddler-editor-border: #cccccc\ntiddler-editor-fields-even: #e0e8e0\ntiddler-editor-fields-odd: #f0f4f0\ntiddler-info-background: #f8f8f8\ntiddler-info-border: #dddddd\ntiddler-info-tab-background: #f8f8f8\ntiddler-link-background: <<colour background>>\ntiddler-link-foreground: <<colour primary>>\ntiddler-subtitle-foreground: #c0c0c0\ntiddler-title-foreground: #182955\ntoolbar-new-button:\ntoolbar-options-button:\ntoolbar-save-button:\ntoolbar-info-button:\ntoolbar-edit-button:\ntoolbar-close-button:\ntoolbar-delete-button:\ntoolbar-cancel-button:\ntoolbar-done-button:\nuntagged-background: #999999\nvery-muted-foreground: #888888\n"
},
"$:/core/readme": {
"title": "$:/core/readme",
"text": "This plugin contains TiddlyWiki's core components, comprising:\n\n* JavaScript code modules\n* Icons\n* Templates needed to create TiddlyWiki's user interface\n* British English (''en-GB'') translations of the localisable strings used by the core\n"
},
"$:/library/sjcl.js/license": {
"title": "$:/library/sjcl.js/license",
"type": "text/plain",
"text": "SJCL is open. You can use, modify and redistribute it under a BSD\nlicense or under the GNU GPL, version 2.0.\n\n---------------------------------------------------------------------\n\nhttp://opensource.org/licenses/BSD-2-Clause\n\nCopyright (c) 2009-2015, Emily Stark, Mike Hamburg and Dan Boneh at\nStanford University. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n1. Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n\n2. Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS\nIS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED\nTO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A\nPARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nHOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\nTO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\nPROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\nLIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\nNEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n---------------------------------------------------------------------\n\nhttp://opensource.org/licenses/GPL-2.0\n\nThe Stanford Javascript Crypto Library (hosted here on GitHub) is a\nproject by the Stanford Computer Security Lab to build a secure,\npowerful, fast, small, easy-to-use, cross-browser library for\ncryptography in Javascript.\n\nCopyright (c) 2009-2015, Emily Stark, Mike Hamburg and Dan Boneh at\nStanford University.\n\nThis program is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License as published by the\nFree Software Foundation; either version 2 of the License, or (at your\noption) any later version.\n\nThis program is distributed in the hope that it will be useful, but\nWITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General\nPublic License for more details.\n\nYou should have received a copy of the GNU General Public License along\nwith this program; if not, write to the Free Software Foundation, Inc.,\n59 Temple Place, Suite 330, Boston, MA 02111-1307 USA"
},
"$:/core/templates/MOTW.html": {
"title": "$:/core/templates/MOTW.html",
"text": "\\rules only filteredtranscludeinline transcludeinline entity\n<!-- The following comment is called a MOTW comment and is necessary for the TiddlyIE Internet Explorer extension -->\n<!-- saved from url=(0021)https://tiddlywiki.com --> "
},
"$:/core/templates/alltiddlers.template.html": {
"title": "$:/core/templates/alltiddlers.template.html",
"type": "text/vnd.tiddlywiki-html",
"text": "<!-- This template is provided for backwards compatibility with older versions of TiddlyWiki -->\n\n<$set name=\"exportFilter\" value=\"[!is[system]sort[title]]\">\n\n{{$:/core/templates/exporters/StaticRiver}}\n\n</$set>\n"
},
"$:/core/templates/canonical-uri-external-image": {
"title": "$:/core/templates/canonical-uri-external-image",
"text": "<!--\n\nThis template is used to assign the ''_canonical_uri'' field to external images.\n\nChange the `./images/` part to a different base URI. The URI can be relative or absolute.\n\n-->\n./images/<$view field=\"title\" format=\"doubleurlencoded\"/>"
},
"$:/core/templates/canonical-uri-external-raw": {
"title": "$:/core/templates/canonical-uri-external-raw",
"text": "<!--\n\nThis template is used to assign the ''_canonical_uri'' field to external raw files that are stored in the same directory\n\n-->\n<$view field=\"title\" format=\"doubleurlencoded\"/>"
},
"$:/core/templates/canonical-uri-external-text": {
"title": "$:/core/templates/canonical-uri-external-text",
"text": "<!--\n\nThis template is used to assign the ''_canonical_uri'' field to external text files.\n\nChange the `./text/` part to a different base URI. The URI can be relative or absolute.\n\n-->\n./text/<$view field=\"title\" format=\"doubleurlencoded\"/>.tid"
},
"$:/core/templates/css-tiddler": {
"title": "$:/core/templates/css-tiddler",
"text": "<!--\n\nThis template is used for saving CSS tiddlers as a style tag with data attributes representing the tiddler fields.\n\n-->`<style`<$fields template=' data-tiddler-$name$=\"$encoded_value$\"'></$fields>` type=\"text/css\">`<$view field=\"text\" format=\"text\" />`</style>`"
},
"$:/core/templates/exporters/CsvFile": {
"title": "$:/core/templates/exporters/CsvFile",
"tags": "$:/tags/Exporter",
"description": "{{$:/language/Exporters/CsvFile}}",
"extension": ".csv",
"text": "\\define renderContent()\n<$text text=<<csvtiddlers filter:\"\"\"$(exportFilter)$\"\"\" format:\"quoted-comma-sep\">>/>\n\\end\n<<renderContent>>\n"
},
"$:/core/templates/exporters/JsonFile": {
"title": "$:/core/templates/exporters/JsonFile",
"tags": "$:/tags/Exporter",
"description": "{{$:/language/Exporters/JsonFile}}",
"extension": ".json",
"text": "\\define renderContent()\n<$text text=<<jsontiddlers filter:\"\"\"$(exportFilter)$\"\"\">>/>\n\\end\n<<renderContent>>\n"
},
"$:/core/templates/exporters/StaticRiver": {
"title": "$:/core/templates/exporters/StaticRiver",
"tags": "$:/tags/Exporter",
"description": "{{$:/language/Exporters/StaticRiver}}",
"extension": ".html",
"text": "\\define tv-wikilink-template() #$uri_encoded$\n\\define tv-config-toolbar-icons() no\n\\define tv-config-toolbar-text() no\n\\define tv-config-toolbar-class() tc-btn-invisible\n\\rules only filteredtranscludeinline transcludeinline\n<!doctype html>\n<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\" />\n<meta name=\"generator\" content=\"TiddlyWiki\" />\n<meta name=\"tiddlywiki-version\" content=\"{{$:/core/templates/version}}\" />\n<meta name=\"format-detection\" content=\"telephone=no\">\n<link id=\"faviconLink\" rel=\"shortcut icon\" href=\"favicon.ico\">\n<title>{{$:/core/wiki/title}}</title>\n<div id=\"styleArea\">\n{{$:/boot/boot.css||$:/core/templates/css-tiddler}}\n</div>\n<style type=\"text/css\">\n{{$:/core/ui/PageStylesheet||$:/core/templates/wikified-tiddler}}\n</style>\n</head>\n<body class=\"tc-body\">\n{{$:/StaticBanner||$:/core/templates/html-tiddler}}\n<section class=\"tc-story-river\">\n{{$:/core/templates/exporters/StaticRiver/Content||$:/core/templates/html-tiddler}}\n</section>\n</body>\n</html>\n"
},
"$:/core/templates/exporters/StaticRiver/Content": {
"title": "$:/core/templates/exporters/StaticRiver/Content",
"text": "\\define renderContent()\n{{{ $(exportFilter)$ ||$:/core/templates/static-tiddler}}}\n\\end\n\\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]\n<<renderContent>>\n"
},
"$:/core/templates/exporters/TidFile": {
"title": "$:/core/templates/exporters/TidFile",
"tags": "$:/tags/Exporter",
"description": "{{$:/language/Exporters/TidFile}}",
"extension": ".tid",
"text": "\\define renderContent()\n{{{ $(exportFilter)$ +[limit[1]] ||$:/core/templates/tid-tiddler}}}\n\\end\n\\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]\n<<renderContent>>"
},
"$:/core/save/all-external-js": {
"title": "$:/core/save/all-external-js",
"text": "\\define saveTiddlerFilter()\n[is[tiddler]] -[prefix[$:/state/popup/]] -[[$:/HistoryList]] -[[$:/core]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]] $(publishFilter)$\n\\end\n{{$:/core/templates/tiddlywiki5-external-js.html}}\n"
},
"$:/core/templates/tiddlywiki5.js": {
"title": "$:/core/templates/tiddlywiki5.js",
"text": "\\rules only filteredtranscludeinline transcludeinline codeinline\n\n/*\n{{ $:/core/copyright.txt ||$:/core/templates/plain-text-tiddler}}\n`*/\n`<!--~~ Library modules ~~-->\n{{{ [is[system]type[application/javascript]library[yes]] ||$:/core/templates/plain-text-tiddler}}}\n<!--~~ Boot prefix ~~-->\n{{ $:/boot/bootprefix.js ||$:/core/templates/plain-text-tiddler}}\n<!--~~ Core plugin ~~-->\n{{$:/core/templates/tiddlywiki5.js/tiddlers}}\n<!--~~ Boot kernel ~~-->\n{{ $:/boot/boot.js ||$:/core/templates/plain-text-tiddler}}\n"
},
"$:/core/templates/tiddlywiki5.js/tiddlers": {
"title": "$:/core/templates/tiddlywiki5.js/tiddlers",
"text": "`\n$tw.preloadTiddlerArray(`<$text text=<<jsontiddlers \"[[$:/core]]\">>/>`);\n$tw.preloadTiddlerArray([{\n\ttitle: \"$:/config/SaveWikiButton/Template\",\n\ttext: \"$:/core/save/all-external-js\"\n}]);\n`\n"
},
"$:/core/templates/tiddlywiki5-external-js.html": {
"title": "$:/core/templates/tiddlywiki5-external-js.html",
"text": "\\rules only filteredtranscludeinline transcludeinline\n<!doctype html>\n{{$:/core/templates/MOTW.html}}<html>\n<head>\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=Edge\">\n<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\" />\n<meta name=\"application-name\" content=\"TiddlyWiki\" />\n<meta name=\"generator\" content=\"TiddlyWiki\" />\n<meta name=\"tiddlywiki-version\" content=\"{{$:/core/templates/version}}\" />\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n<meta name=\"apple-mobile-web-app-capable\" content=\"yes\" />\n<meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black-translucent\" />\n<meta name=\"mobile-web-app-capable\" content=\"yes\"/>\n<meta name=\"format-detection\" content=\"telephone=no\" />\n<meta name=\"copyright\" content=\"{{$:/core/copyright.txt}}\" />\n<link id=\"faviconLink\" rel=\"shortcut icon\" href=\"favicon.ico\">\n<title>{{$:/core/wiki/title}}</title>\n<!--~~ This is a Tiddlywiki file. The points of interest in the file are marked with this pattern ~~-->\n\n<!--~~ Raw markup ~~-->\n{{{ [all[shadows+tiddlers]tag[$:/core/wiki/rawmarkup]] [all[shadows+tiddlers]tag[$:/tags/RawMarkup]] ||$:/core/templates/plain-text-tiddler}}}\n{{{ [all[shadows+tiddlers]tag[$:/tags/RawMarkupWikified]] ||$:/core/templates/raw-static-tiddler}}}\n</head>\n<body class=\"tc-body\">\n<!--~~ Static styles ~~-->\n<div id=\"styleArea\">\n{{$:/boot/boot.css||$:/core/templates/css-tiddler}}\n</div>\n<!--~~ Static content for Google and browsers without JavaScript ~~-->\n<noscript>\n<div id=\"splashArea\">\n{{$:/core/templates/static.area}}\n</div>\n</noscript>\n<!--~~ Ordinary tiddlers ~~-->\n{{$:/core/templates/store.area.template.html}}\n</body>\n<script src=\"%24%3A%2Fcore%2Ftemplates%2Ftiddlywiki5.js\" onerror=\"alert('Error: Cannot load tiddlywiki.js');\"></script>\n</html>\n"
},
"$:/core/templates/html-div-tiddler": {
"title": "$:/core/templates/html-div-tiddler",
"text": "<!--\n\nThis template is used for saving tiddlers as an HTML DIV tag with attributes representing the tiddler fields.\n\n-->`<div`<$fields template=' $name$=\"$encoded_value$\"'></$fields>`>\n<pre>`<$view field=\"text\" format=\"htmlencoded\" />`</pre>\n</div>`\n"
},
"$:/core/templates/html-tiddler": {
"title": "$:/core/templates/html-tiddler",
"text": "<!--\n\nThis template is used for saving tiddlers as raw HTML\n\n--><$view field=\"text\" format=\"htmlwikified\" />"
},
"$:/core/templates/javascript-tiddler": {
"title": "$:/core/templates/javascript-tiddler",
"text": "<!--\n\nThis template is used for saving JavaScript tiddlers as a script tag with data attributes representing the tiddler fields.\n\n-->`<script`<$fields template=' data-tiddler-$name$=\"$encoded_value$\"'></$fields>` type=\"text/javascript\">`<$view field=\"text\" format=\"text\" />`</script>`"
},
"$:/core/templates/json-tiddler": {
"title": "$:/core/templates/json-tiddler",
"text": "<!--\n\nThis template is used for saving tiddlers as raw JSON\n\n--><$text text=<<jsontiddler>>/>"
},
"$:/core/templates/module-tiddler": {
"title": "$:/core/templates/module-tiddler",
"text": "<!--\n\nThis template is used for saving JavaScript tiddlers as a script tag with data attributes representing the tiddler fields. The body of the tiddler is wrapped in a call to the `$tw.modules.define` function in order to define the body of the tiddler as a module\n\n-->`<script`<$fields template=' data-tiddler-$name$=\"$encoded_value$\"'></$fields>` type=\"text/javascript\" data-module=\"yes\">$tw.modules.define(\"`<$view field=\"title\" format=\"jsencoded\" />`\",\"`<$view field=\"module-type\" format=\"jsencoded\" />`\",function(module,exports,require) {`<$view field=\"text\" format=\"text\" />`});\n</script>`"
},
"$:/core/templates/plain-text-tiddler": {
"title": "$:/core/templates/plain-text-tiddler",
"text": "<$view field=\"text\" format=\"text\" />"
},
"$:/core/templates/raw-static-tiddler": {
"title": "$:/core/templates/raw-static-tiddler",
"text": "<!--\n\nThis template is used for saving tiddlers as static HTML\n\n--><$view field=\"text\" format=\"plainwikified\" />"
},
"$:/core/save/all": {
"title": "$:/core/save/all",
"text": "\\define saveTiddlerFilter()\n[is[tiddler]] -[prefix[$:/state/popup/]] -[[$:/HistoryList]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]] $(publishFilter)$\n\\end\n{{$:/core/templates/tiddlywiki5.html}}\n"
},
"$:/core/save/empty": {
"title": "$:/core/save/empty",
"text": "\\define saveTiddlerFilter()\n[is[system]] -[prefix[$:/state/popup/]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]]\n\\end\n{{$:/core/templates/tiddlywiki5.html}}\n"
},
"$:/core/save/lazy-all": {
"title": "$:/core/save/lazy-all",
"text": "\\define saveTiddlerFilter()\n[is[system]] -[prefix[$:/state/popup/]] -[[$:/HistoryList]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]] \n\\end\n{{$:/core/templates/tiddlywiki5.html}}\n"
},
"$:/core/save/lazy-images": {
"title": "$:/core/save/lazy-images",
"text": "\\define saveTiddlerFilter()\n[is[tiddler]] -[prefix[$:/state/popup/]] -[[$:/HistoryList]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] -[!is[system]is[image]] +[sort[title]] \n\\end\n{{$:/core/templates/tiddlywiki5.html}}\n"
},
"$:/core/templates/server/static.sidebar.wikitext": {
"title": "$:/core/templates/server/static.sidebar.wikitext",
"text": "\\whitespace trim\n<div class=\"tc-sidebar-scrollable\" style=\"overflow: auto;\">\n<div class=\"tc-sidebar-header\">\n<h1 class=\"tc-site-title\">\n<$transclude tiddler=\"$:/SiteTitle\"/>\n</h1>\n<div class=\"tc-site-subtitle\">\n<$transclude tiddler=\"$:/SiteSubtitle\"/>\n</div>\n<h2>\n</h2>\n<div class=\"tc-sidebar-lists\">\n<$list filter={{$:/DefaultTiddlers}}>\n<div class=\"tc-menu-list-subitem\">\n<$link><$text text=<<currentTiddler>>/></$link>\n</div>\n</$list>\n</div>\n<!-- Currently disabled the recent list as it is unweildy when the responsive narrow view kicks in\n<h2>\n{{$:/language/SideBar/Recent/Caption}}\n</h2>\n<div class=\"tc-sidebar-lists\">\n<$macrocall $name=\"timeline\" format={{$:/language/RecentChanges/DateFormat}}/>\n</div>\n</div>\n</div>\n-->\n"
},
"$:/core/templates/server/static.tiddler.html": {
"title": "$:/core/templates/server/static.tiddler.html",
"text": "\\whitespace trim\n\\define tv-wikilink-template() $uri_encoded$\n\\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]\n<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\" />\n<meta name=\"generator\" content=\"TiddlyWiki\" />\n<meta name=\"tiddlywiki-version\" content={{$:/core/templates/version}} />\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n<meta name=\"apple-mobile-web-app-capable\" content=\"yes\" />\n<meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black-translucent\" />\n<meta name=\"mobile-web-app-capable\" content=\"yes\"/>\n<meta name=\"format-detection\" content=\"telephone=no\">\n<link id=\"faviconLink\" rel=\"shortcut icon\" href=\"favicon.ico\">\n<link rel=\"stylesheet\" href=\"%24%3A%2Fcore%2Ftemplates%2Fstatic.template.css\">\n<title><$view field=\"caption\" format=\"plainwikified\"><$view field=\"title\"/></$view>: <$view tiddler=\"$:/core/wiki/title\" format=\"plainwikified\"/></title>\n</head>\n<body class=\"tc-body\">\n<$transclude tiddler=\"$:/core/templates/server/static.sidebar.wikitext\" mode=\"inline\"/>\n<section class=\"tc-story-river\">\n<div class=\"tc-tiddler-frame\">\n<$transclude tiddler=\"$:/core/templates/server/static.tiddler.wikitext\" mode=\"inline\"/>\n</div>\n</section>\n</body>\n</html>"
},
"$:/core/templates/server/static.tiddler.wikitext": {
"title": "$:/core/templates/server/static.tiddler.wikitext",
"text": "\\whitespace trim\n<div class=\"tc-tiddler-title\">\n<div class=\"tc-titlebar\">\n<h2><$text text=<<currentTiddler>>/></h2>\n</div>\n</div>\n<div class=\"tc-subtitle\">\n<$link to={{!!modifier}}>\n<$view field=\"modifier\"/>\n</$link> <$view field=\"modified\" format=\"date\" template={{$:/language/Tiddler/DateFormat}}/>\n</div>\n<div class=\"tc-tags-wrapper\">\n<$list filter=\"[all[current]tags[]sort[title]]\">\n<a href={{{ [<currentTiddler>encodeuricomponent[]] }}}>\n<$macrocall $name=\"tag-pill\" tag=<<currentTiddler>>/>\n</a>\n</$list>\n</div>\n<div class=\"tc-tiddler-body\">\n<$transclude mode=\"block\"/>\n</div>\n"
},
"$:/core/templates/single.tiddler.window": {
"title": "$:/core/templates/single.tiddler.window",
"text": "<$set name=\"themeTitle\" value={{$:/view}}>\n\n<$set name=\"tempCurrentTiddler\" value=<<currentTiddler>>>\n\n<$set name=\"currentTiddler\" value={{$:/language}}>\n\n<$set name=\"languageTitle\" value={{!!name}}>\n\n<$set name=\"currentTiddler\" value=<<tempCurrentTiddler>>>\n\n<$importvariables filter=\"[[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]\">\n\n<$navigator story=\"$:/StoryList\" history=\"$:/HistoryList\">\n\n<$transclude mode=\"block\"/>\n\n</$navigator>\n\n</$importvariables>\n\n</$set>\n\n</$set>\n\n</$set>\n\n</$set>\n\n</$set>\n\n"
},
"$:/core/templates/split-recipe": {
"title": "$:/core/templates/split-recipe",
"text": "<$list filter=\"[!is[system]]\">\ntiddler: <$view field=\"title\" format=\"urlencoded\"/>.tid\n</$list>\n"
},
"$:/core/templates/static-tiddler": {
"title": "$:/core/templates/static-tiddler",
"text": "<a name=<<currentTiddler>>>\n<$transclude tiddler=\"$:/core/ui/ViewTemplate\"/>\n</a>"
},
"$:/core/templates/static.area": {
"title": "$:/core/templates/static.area",
"text": "<$reveal type=\"nomatch\" state=\"$:/isEncrypted\" text=\"yes\">\n{{{ [all[shadows+tiddlers]tag[$:/tags/RawStaticContent]!has[draft.of]] ||$:/core/templates/raw-static-tiddler}}}\n{{$:/core/templates/static.content||$:/core/templates/html-tiddler}}\n</$reveal>\n<$reveal type=\"match\" state=\"$:/isEncrypted\" text=\"yes\">\nThis file contains an encrypted ~TiddlyWiki. Enable ~JavaScript and enter the decryption password when prompted.\n</$reveal>\n"
},
"$:/core/templates/static.content": {
"title": "$:/core/templates/static.content",
"text": "<!-- For Google, and people without JavaScript-->\nThis [[TiddlyWiki|https://tiddlywiki.com]] contains the following tiddlers:\n\n<ul>\n<$list filter=<<saveTiddlerFilter>>>\n<li><$view field=\"title\" format=\"text\"></$view></li>\n</$list>\n</ul>\n"
},
"$:/core/templates/static.template.css": {
"title": "$:/core/templates/static.template.css",
"text": "{{$:/boot/boot.css||$:/core/templates/plain-text-tiddler}}\n\n{{$:/core/ui/PageStylesheet||$:/core/templates/wikified-tiddler}}\n"
},
"$:/core/templates/static.template.html": {
"title": "$:/core/templates/static.template.html",
"type": "text/vnd.tiddlywiki-html",
"text": "\\define tv-wikilink-template() static/$uri_doubleencoded$.html\n\\define tv-config-toolbar-icons() no\n\\define tv-config-toolbar-text() no\n\\define tv-config-toolbar-class() tc-btn-invisible\n\\rules only filteredtranscludeinline transcludeinline\n<!doctype html>\n<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\" />\n<meta name=\"generator\" content=\"TiddlyWiki\" />\n<meta name=\"tiddlywiki-version\" content=\"{{$:/core/templates/version}}\" />\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n<meta name=\"apple-mobile-web-app-capable\" content=\"yes\" />\n<meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black-translucent\" />\n<meta name=\"mobile-web-app-capable\" content=\"yes\"/>\n<meta name=\"format-detection\" content=\"telephone=no\">\n<link id=\"faviconLink\" rel=\"shortcut icon\" href=\"favicon.ico\">\n<title>{{$:/core/wiki/title}}</title>\n<div id=\"styleArea\">\n{{$:/boot/boot.css||$:/core/templates/css-tiddler}}\n</div>\n<style type=\"text/css\">\n{{$:/core/ui/PageStylesheet||$:/core/templates/wikified-tiddler}}\n</style>\n</head>\n<body class=\"tc-body\">\n{{$:/StaticBanner||$:/core/templates/html-tiddler}}\n{{$:/core/ui/PageTemplate||$:/core/templates/html-tiddler}}\n</body>\n</html>\n"
},
"$:/core/templates/static.tiddler.html": {
"title": "$:/core/templates/static.tiddler.html",
"text": "\\define tv-wikilink-template() $uri_doubleencoded$.html\n\\define tv-config-toolbar-icons() no\n\\define tv-config-toolbar-text() no\n\\define tv-config-toolbar-class() tc-btn-invisible\n\\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]\n`<!doctype html>\n<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\" />\n<meta name=\"generator\" content=\"TiddlyWiki\" />\n<meta name=\"tiddlywiki-version\" content=\"`{{$:/core/templates/version}}`\" />\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n<meta name=\"apple-mobile-web-app-capable\" content=\"yes\" />\n<meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black-translucent\" />\n<meta name=\"mobile-web-app-capable\" content=\"yes\"/>\n<meta name=\"format-detection\" content=\"telephone=no\">\n<link id=\"faviconLink\" rel=\"shortcut icon\" href=\"favicon.ico\">\n<link rel=\"stylesheet\" href=\"static.css\">\n<title>`<$view field=\"caption\"><$view field=\"title\"/></$view>: {{$:/core/wiki/title}}`</title>\n</head>\n<body class=\"tc-body\">\n`{{$:/StaticBanner||$:/core/templates/html-tiddler}}`\n<section class=\"tc-story-river\">\n`<$view tiddler=\"$:/core/ui/ViewTemplate\" format=\"htmlwikified\"/>`\n</section>\n</body>\n</html>\n`"
},
"$:/core/templates/store.area.template.html": {
"title": "$:/core/templates/store.area.template.html",
"text": "<$reveal type=\"nomatch\" state=\"$:/isEncrypted\" text=\"yes\">\n`<div id=\"storeArea\" style=\"display:none;\">`\n<$list filter=<<saveTiddlerFilter>> template=\"$:/core/templates/html-div-tiddler\"/>\n`</div>`\n</$reveal>\n<$reveal type=\"match\" state=\"$:/isEncrypted\" text=\"yes\">\n`<!--~~ Encrypted tiddlers ~~-->`\n`<pre id=\"encryptedStoreArea\" type=\"text/plain\" style=\"display:none;\">`\n<$encrypt filter=<<saveTiddlerFilter>>/>\n`</pre>`\n</$reveal>"
},
"$:/core/templates/tid-tiddler": {
"title": "$:/core/templates/tid-tiddler",
"text": "<!--\n\nThis template is used for saving tiddlers in TiddlyWeb *.tid format\n\n--><$fields exclude='text bag' template='$name$: $value$\n'></$fields>`\n`<$view field=\"text\" format=\"text\" />"
},
"$:/core/templates/tiddler-metadata": {
"title": "$:/core/templates/tiddler-metadata",
"text": "<!--\n\nThis template is used for saving tiddler metadata *.meta files\n\n--><$fields exclude='text bag' template='$name$: $value$\n'></$fields>"
},
"$:/core/templates/tiddlywiki5.html": {
"title": "$:/core/templates/tiddlywiki5.html",
"text": "\\rules only filteredtranscludeinline transcludeinline\n<!doctype html>\n{{$:/core/templates/MOTW.html}}<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\" />\n<!--~~ Raw markup for the top of the head section ~~-->\n{{{ [all[shadows+tiddlers]tag[$:/tags/RawMarkupWikified/TopHead]] ||$:/core/templates/raw-static-tiddler}}}\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=Edge\"/>\n<meta name=\"application-name\" content=\"TiddlyWiki\" />\n<meta name=\"generator\" content=\"TiddlyWiki\" />\n<meta name=\"tiddlywiki-version\" content=\"{{$:/core/templates/version}}\" />\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n<meta name=\"apple-mobile-web-app-capable\" content=\"yes\" />\n<meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black-translucent\" />\n<meta name=\"mobile-web-app-capable\" content=\"yes\"/>\n<meta name=\"format-detection\" content=\"telephone=no\" />\n<meta name=\"copyright\" content=\"{{$:/core/copyright.txt}}\" />\n<link id=\"faviconLink\" rel=\"shortcut icon\" href=\"favicon.ico\">\n<title>{{$:/core/wiki/title}}</title>\n<!--~~ This is a Tiddlywiki file. The points of interest in the file are marked with this pattern ~~-->\n\n<!--~~ Raw markup ~~-->\n{{{ [all[shadows+tiddlers]tag[$:/core/wiki/rawmarkup]] [all[shadows+tiddlers]tag[$:/tags/RawMarkup]] ||$:/core/templates/plain-text-tiddler}}}\n{{{ [all[shadows+tiddlers]tag[$:/tags/RawMarkupWikified]] ||$:/core/templates/raw-static-tiddler}}}\n</head>\n<body class=\"tc-body\">\n<!--~~ Raw markup for the top of the body section ~~-->\n{{{ [all[shadows+tiddlers]tag[$:/tags/RawMarkupWikified/TopBody]] ||$:/core/templates/raw-static-tiddler}}}\n<!--~~ Static styles ~~-->\n<div id=\"styleArea\">\n{{$:/boot/boot.css||$:/core/templates/css-tiddler}}\n</div>\n<!--~~ Static content for Google and browsers without JavaScript ~~-->\n<noscript>\n<div id=\"splashArea\">\n{{$:/core/templates/static.area}}\n</div>\n</noscript>\n<!--~~ Ordinary tiddlers ~~-->\n{{$:/core/templates/store.area.template.html}}\n<!--~~ Library modules ~~-->\n<div id=\"libraryModules\" style=\"display:none;\">\n{{{ [is[system]type[application/javascript]library[yes]] ||$:/core/templates/javascript-tiddler}}}\n</div>\n<!--~~ Boot kernel prologue ~~-->\n<div id=\"bootKernelPrefix\" style=\"display:none;\">\n{{ $:/boot/bootprefix.js ||$:/core/templates/javascript-tiddler}}\n</div>\n<!--~~ Boot kernel ~~-->\n<div id=\"bootKernel\" style=\"display:none;\">\n{{ $:/boot/boot.js ||$:/core/templates/javascript-tiddler}}\n</div>\n<!--~~ Raw markup for the bottom of the body section ~~-->\n{{{ [all[shadows+tiddlers]tag[$:/tags/RawMarkupWikified/BottomBody]] ||$:/core/templates/raw-static-tiddler}}}\n</body>\n</html>\n"
},
"$:/core/templates/version": {
"title": "$:/core/templates/version",
"text": "<<version>>"
},
"$:/core/templates/wikified-tiddler": {
"title": "$:/core/templates/wikified-tiddler",
"text": "<$transclude />"
},
"$:/core/ui/AboveStory/tw2-plugin-check": {
"title": "$:/core/ui/AboveStory/tw2-plugin-check",
"tags": "$:/tags/AboveStory",
"text": "\\define lingo-base() $:/language/AboveStory/ClassicPlugin/\n<$list filter=\"[all[system+tiddlers]tag[systemConfig]limit[1]]\">\n\n<div class=\"tc-message-box\">\n\n<<lingo Warning>>\n\n<ul>\n\n<$list filter=\"[all[system+tiddlers]tag[systemConfig]]\">\n\n<li>\n\n<$link><$view field=\"title\"/></$link>\n\n</li>\n\n</$list>\n\n</ul>\n\n</div>\n\n</$list>\n"
},
"$:/core/ui/Actions/new-image": {
"title": "$:/core/ui/Actions/new-image",
"tags": "$:/tags/Actions",
"description": "create a new image tiddler",
"text": "\\define get-type()\nimage/$(imageType)$\n\\end\n<$vars imageType={{$:/config/NewImageType}}>\n<$action-sendmessage $message=\"tm-new-tiddler\" type=<<get-type>>/>\n</$vars>\n"
},
"$:/core/ui/Actions/new-journal": {
"title": "$:/core/ui/Actions/new-journal",
"tags": "$:/tags/Actions",
"description": "create a new journal tiddler",
"text": "<$vars journalTitleTemplate={{$:/config/NewJournal/Title}} journalTags={{$:/config/NewJournal/Tags}} journalText={{$:/config/NewJournal/Text}}>\n<$wikify name=\"journalTitle\" text=\"\"\"<$macrocall $name=\"now\" format=<<journalTitleTemplate>>/>\"\"\">\n<$reveal type=\"nomatch\" state=<<journalTitle>> text=\"\">\n<$action-sendmessage $message=\"tm-new-tiddler\" title=<<journalTitle>> tags=<<journalTags>> text={{{ [<journalTitle>get[]] }}}/>\n</$reveal>\n<$reveal type=\"match\" state=<<journalTitle>> text=\"\">\n<$action-sendmessage $message=\"tm-new-tiddler\" title=<<journalTitle>> tags=<<journalTags>> text=<<journalText>>/>\n</$reveal>\n</$wikify>\n</$vars>\n"
},
"$:/core/ui/Actions/new-tiddler": {
"title": "$:/core/ui/Actions/new-tiddler",
"tags": "$:/tags/Actions",
"description": "create a new empty tiddler",
"text": "<$action-sendmessage $message=\"tm-new-tiddler\"/>\n"
},
"$:/core/ui/AdvancedSearch/Filter": {
"title": "$:/core/ui/AdvancedSearch/Filter",
"tags": "$:/tags/AdvancedSearch",
"caption": "{{$:/language/Search/Filter/Caption}}",
"text": "\\define lingo-base() $:/language/Search/\n<<lingo Filter/Hint>>\n\n<div class=\"tc-search tc-advanced-search\">\n<$edit-text tiddler=\"$:/temp/advancedsearch\" type=\"search\" tag=\"input\"/>\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/AdvancedSearch/FilterButton]!has[draft.of]]\"><$transclude/></$list>\n</div>\n\n<$reveal state=\"$:/temp/advancedsearch\" type=\"nomatch\" text=\"\">\n<$set name=\"resultCount\" value=\"\"\"<$count filter={{$:/temp/advancedsearch}}/>\"\"\">\n<div class=\"tc-search-results\">\n<<lingo Filter/Matches>>\n<$list filter={{$:/temp/advancedsearch}} template=\"$:/core/ui/ListItemTemplate\"/>\n</div>\n</$set>\n</$reveal>\n"
},
"$:/core/ui/AdvancedSearch/Filter/FilterButtons/clear": {
"title": "$:/core/ui/AdvancedSearch/Filter/FilterButtons/clear",
"tags": "$:/tags/AdvancedSearch/FilterButton",
"text": "<$reveal state=\"$:/temp/advancedsearch\" type=\"nomatch\" text=\"\">\n<$button class=\"tc-btn-invisible\">\n<$action-setfield $tiddler=\"$:/temp/advancedsearch\" $field=\"text\" $value=\"\"/>\n{{$:/core/images/close-button}}\n</$button>\n</$reveal>\n"
},
"$:/core/ui/AdvancedSearch/Filter/FilterButtons/delete": {
"title": "$:/core/ui/AdvancedSearch/Filter/FilterButtons/delete",
"tags": "$:/tags/AdvancedSearch/FilterButton",
"text": "<$reveal state=\"$:/temp/advancedsearch\" type=\"nomatch\" text=\"\">\n<$button popup=<<qualify \"$:/state/filterDeleteDropdown\">> class=\"tc-btn-invisible\">\n{{$:/core/images/delete-button}}\n</$button>\n</$reveal>\n\n<$reveal state=<<qualify \"$:/state/filterDeleteDropdown\">> type=\"popup\" position=\"belowleft\" animate=\"yes\">\n<div class=\"tc-block-dropdown-wrapper\">\n<div class=\"tc-block-dropdown tc-edit-type-dropdown\">\n<div class=\"tc-dropdown-item-plain\">\n<$set name=\"resultCount\" value=\"\"\"<$count filter={{$:/temp/advancedsearch}}/>\"\"\">\nAre you sure you wish to delete <<resultCount>> tiddler(s)?\n</$set>\n</div>\n<div class=\"tc-dropdown-item-plain\">\n<$button class=\"tc-btn\">\n<$action-deletetiddler $filter={{$:/temp/advancedsearch}}/>\nDelete these tiddlers\n</$button>\n</div>\n</div>\n</div>\n</$reveal>\n"
},
"$:/core/ui/AdvancedSearch/Filter/FilterButtons/dropdown": {
"title": "$:/core/ui/AdvancedSearch/Filter/FilterButtons/dropdown",
"tags": "$:/tags/AdvancedSearch/FilterButton",
"text": "<span class=\"tc-popup-keep\">\n<$button popup=<<qualify \"$:/state/filterDropdown\">> class=\"tc-btn-invisible\">\n{{$:/core/images/down-arrow}}\n</$button>\n</span>\n\n<$reveal state=<<qualify \"$:/state/filterDropdown\">> type=\"popup\" position=\"belowleft\" animate=\"yes\">\n<$set name=\"tv-show-missing-links\" value=\"yes\">\n<$linkcatcher to=\"$:/temp/advancedsearch\">\n<div class=\"tc-block-dropdown-wrapper\">\n<div class=\"tc-block-dropdown tc-edit-type-dropdown\">\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/Filter]]\"><$link to={{!!filter}}><$transclude field=\"description\"/></$link>\n</$list>\n</div>\n</div>\n</$linkcatcher>\n</$set>\n</$reveal>\n"
},
"$:/core/ui/AdvancedSearch/Filter/FilterButtons/export": {
"title": "$:/core/ui/AdvancedSearch/Filter/FilterButtons/export",
"tags": "$:/tags/AdvancedSearch/FilterButton",
"text": "<$reveal state=\"$:/temp/advancedsearch\" type=\"nomatch\" text=\"\">\n<$macrocall $name=\"exportButton\" exportFilter={{$:/temp/advancedsearch}} lingoBase=\"$:/language/Buttons/ExportTiddlers/\"/>\n</$reveal>\n"
},
"$:/core/ui/AdvancedSearch/Shadows": {
"title": "$:/core/ui/AdvancedSearch/Shadows",
"tags": "$:/tags/AdvancedSearch",
"caption": "{{$:/language/Search/Shadows/Caption}}",
"text": "\\define lingo-base() $:/language/Search/\n<$linkcatcher to=\"$:/temp/advancedsearch\">\n\n<<lingo Shadows/Hint>>\n\n<div class=\"tc-search\">\n<$edit-text tiddler=\"$:/temp/advancedsearch\" type=\"search\" tag=\"input\"/>\n<$reveal state=\"$:/temp/advancedsearch\" type=\"nomatch\" text=\"\">\n<$button class=\"tc-btn-invisible\">\n<$action-setfield $tiddler=\"$:/temp/advancedsearch\" $field=\"text\" $value=\"\"/>\n{{$:/core/images/close-button}}\n</$button>\n</$reveal>\n</div>\n\n</$linkcatcher>\n\n<$reveal state=\"$:/temp/advancedsearch\" type=\"nomatch\" text=\"\">\n\n<$list filter=\"[{$:/temp/advancedsearch}minlength{$:/config/Search/MinLength}limit[1]]\" emptyMessage=\"\"\"<div class=\"tc-search-results\">{{$:/language/Search/Search/TooShort}}</div>\"\"\" variable=\"listItem\">\n\n<$set name=\"resultCount\" value=\"\"\"<$count filter=\"[all[shadows]search{$:/temp/advancedsearch}] -[[$:/temp/advancedsearch]]\"/>\"\"\">\n\n<div class=\"tc-search-results\">\n\n<<lingo Shadows/Matches>>\n\n<$list filter=\"[all[shadows]search{$:/temp/advancedsearch}sort[title]limit[250]] -[[$:/temp/advancedsearch]]\" template=\"$:/core/ui/ListItemTemplate\"/>\n\n</div>\n\n</$set>\n\n</$list>\n\n</$reveal>\n\n<$reveal state=\"$:/temp/advancedsearch\" type=\"match\" text=\"\">\n\n</$reveal>\n"
},
"$:/core/ui/AdvancedSearch/Standard": {
"title": "$:/core/ui/AdvancedSearch/Standard",
"tags": "$:/tags/AdvancedSearch",
"caption": "{{$:/language/Search/Standard/Caption}}",
"text": "\\define lingo-base() $:/language/Search/\n<$linkcatcher to=\"$:/temp/advancedsearch\">\n\n<<lingo Standard/Hint>>\n\n<div class=\"tc-search\">\n<$edit-text tiddler=\"$:/temp/advancedsearch\" type=\"search\" tag=\"input\"/>\n<$reveal state=\"$:/temp/advancedsearch\" type=\"nomatch\" text=\"\">\n<$button class=\"tc-btn-invisible\">\n<$action-setfield $tiddler=\"$:/temp/advancedsearch\" $field=\"text\" $value=\"\"/>\n{{$:/core/images/close-button}}\n</$button>\n</$reveal>\n</div>\n\n</$linkcatcher>\n\n<$reveal state=\"$:/temp/advancedsearch\" type=\"nomatch\" text=\"\">\n<$list filter=\"[{$:/temp/advancedsearch}minlength{$:/config/Search/MinLength}limit[1]]\" emptyMessage=\"\"\"<div class=\"tc-search-results\">{{$:/language/Search/Search/TooShort}}</div>\"\"\" variable=\"listItem\">\n<$set name=\"searchTiddler\" value=\"$:/temp/advancedsearch\">\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/SearchResults]!has[draft.of]butfirst[]limit[1]]\" emptyMessage=\"\"\"\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/SearchResults]!has[draft.of]]\">\n<$transclude/>\n</$list>\n\"\"\">\n<$macrocall $name=\"tabs\" tabsList=\"[all[shadows+tiddlers]tag[$:/tags/SearchResults]!has[draft.of]]\" default={{$:/config/SearchResults/Default}}/>\n</$list>\n</$set>\n</$list>\n</$reveal>\n"
},
"$:/core/ui/AdvancedSearch/System": {
"title": "$:/core/ui/AdvancedSearch/System",
"tags": "$:/tags/AdvancedSearch",
"caption": "{{$:/language/Search/System/Caption}}",
"text": "\\define lingo-base() $:/language/Search/\n<$linkcatcher to=\"$:/temp/advancedsearch\">\n\n<<lingo System/Hint>>\n\n<div class=\"tc-search\">\n<$edit-text tiddler=\"$:/temp/advancedsearch\" type=\"search\" tag=\"input\"/>\n<$reveal state=\"$:/temp/advancedsearch\" type=\"nomatch\" text=\"\">\n<$button class=\"tc-btn-invisible\">\n<$action-setfield $tiddler=\"$:/temp/advancedsearch\" $field=\"text\" $value=\"\"/>\n{{$:/core/images/close-button}}\n</$button>\n</$reveal>\n</div>\n\n</$linkcatcher>\n\n<$reveal state=\"$:/temp/advancedsearch\" type=\"nomatch\" text=\"\">\n\n<$list filter=\"[{$:/temp/advancedsearch}minlength{$:/config/Search/MinLength}limit[1]]\" emptyMessage=\"\"\"<div class=\"tc-search-results\">{{$:/language/Search/Search/TooShort}}</div>\"\"\" variable=\"listItem\">\n\n<$set name=\"resultCount\" value=\"\"\"<$count filter=\"[is[system]search{$:/temp/advancedsearch}] -[[$:/temp/advancedsearch]]\"/>\"\"\">\n\n<div class=\"tc-search-results\">\n\n<<lingo System/Matches>>\n\n<$list filter=\"[is[system]search{$:/temp/advancedsearch}sort[title]limit[250]] -[[$:/temp/advancedsearch]]\" template=\"$:/core/ui/ListItemTemplate\"/>\n\n</div>\n\n</$set>\n\n</$list>\n\n</$reveal>\n\n<$reveal state=\"$:/temp/advancedsearch\" type=\"match\" text=\"\">\n\n</$reveal>\n"
},
"$:/AdvancedSearch": {
"title": "$:/AdvancedSearch",
"icon": "$:/core/images/advanced-search-button",
"color": "#bbb",
"text": "<div class=\"tc-advanced-search\">\n<<tabs \"[all[shadows+tiddlers]tag[$:/tags/AdvancedSearch]!has[draft.of]]\" \"$:/core/ui/AdvancedSearch/System\">>\n</div>\n"
},
"$:/core/ui/AlertTemplate": {
"title": "$:/core/ui/AlertTemplate",
"text": "<div class=\"tc-alert\">\n<div class=\"tc-alert-toolbar\">\n<$button class=\"tc-btn-invisible\"><$action-deletetiddler $tiddler=<<currentTiddler>>/>{{$:/core/images/delete-button}}</$button>\n</div>\n<div class=\"tc-alert-subtitle\">\n<$view field=\"component\"/> - <$view field=\"modified\" format=\"date\" template=\"0hh:0mm:0ss DD MM YYYY\"/> <$reveal type=\"nomatch\" state=\"!!count\" text=\"\"><span class=\"tc-alert-highlight\">({{$:/language/Count}}: <$view field=\"count\"/>)</span></$reveal>\n</div>\n<div class=\"tc-alert-body\">\n\n<$transclude/>\n\n</div>\n</div>\n"
},
"$:/core/ui/BinaryWarning": {
"title": "$:/core/ui/BinaryWarning",
"text": "\\define lingo-base() $:/language/BinaryWarning/\n<div class=\"tc-binary-warning\">\n\n<<lingo Prompt>>\n\n</div>\n"
},
"$:/core/ui/Components/plugin-info": {
"title": "$:/core/ui/Components/plugin-info",
"text": "\\define lingo-base() $:/language/ControlPanel/Plugins/\n\n\\define popup-state-macro()\n$(qualified-state)$-$(currentTiddler)$\n\\end\n\n\\define tabs-state-macro()\n$(popup-state)$-$(pluginInfoType)$\n\\end\n\n\\define plugin-icon-title()\n$(currentTiddler)$/icon\n\\end\n\n\\define plugin-disable-title()\n$:/config/Plugins/Disabled/$(currentTiddler)$\n\\end\n\n\\define plugin-table-body(type,disabledMessage,default-popup-state)\n<div class=\"tc-plugin-info-chunk tc-small-icon\">\n<$reveal type=\"nomatch\" state=<<popup-state>> text=\"yes\" default=\"\"\"$default-popup-state$\"\"\">\n<$button class=\"tc-btn-invisible tc-btn-dropdown\" set=<<popup-state>> setTo=\"yes\">\n{{$:/core/images/right-arrow}}\n</$button>\n</$reveal>\n<$reveal type=\"match\" state=<<popup-state>> text=\"yes\" default=\"\"\"$default-popup-state$\"\"\">\n<$button class=\"tc-btn-invisible tc-btn-dropdown\" set=<<popup-state>> setTo=\"no\">\n{{$:/core/images/down-arrow}}\n</$button>\n</$reveal>\n</div>\n<div class=\"tc-plugin-info-chunk\">\n<$transclude tiddler=<<currentTiddler>> subtiddler=<<plugin-icon-title>>>\n<$transclude tiddler=\"$:/core/images/plugin-generic-$type$\"/>\n</$transclude>\n</div>\n<div class=\"tc-plugin-info-chunk\">\n<h1>\n''<$view field=\"description\"><$view field=\"title\"/></$view>'' $disabledMessage$\n</h1>\n<h2>\n<$view field=\"title\"/>\n</h2>\n<h2>\n<div><em><$view field=\"version\"/></em></div>\n</h2>\n</div>\n\\end\n\n\\define plugin-info(type,default-popup-state)\n<$set name=\"popup-state\" value=<<popup-state-macro>>>\n<$reveal type=\"nomatch\" state=<<plugin-disable-title>> text=\"yes\">\n<$link to={{!!title}} class=\"tc-plugin-info\">\n<<plugin-table-body type:\"$type$\" default-popup-state:\"\"\"$default-popup-state$\"\"\">>\n</$link>\n</$reveal>\n<$reveal type=\"match\" state=<<plugin-disable-title>> text=\"yes\">\n<$link to={{!!title}} class=\"tc-plugin-info tc-plugin-info-disabled\">\n<<plugin-table-body type:\"$type$\" default-popup-state:\"\"\"$default-popup-state$\"\"\" disabledMessage:\"<$macrocall $name='lingo' title='Disabled/Status'/>\">>\n</$link>\n</$reveal>\n<$reveal type=\"match\" text=\"yes\" state=<<popup-state>> default=\"\"\"$default-popup-state$\"\"\">\n<div class=\"tc-plugin-info-dropdown\">\n<div class=\"tc-plugin-info-dropdown-body\">\n<$list filter=\"[all[current]] -[[$:/core]]\">\n<div style=\"float:right;\">\n<$reveal type=\"nomatch\" state=<<plugin-disable-title>> text=\"yes\">\n<$button set=<<plugin-disable-title>> setTo=\"yes\" tooltip={{$:/language/ControlPanel/Plugins/Disable/Hint}} aria-label={{$:/language/ControlPanel/Plugins/Disable/Caption}}>\n<<lingo Disable/Caption>>\n</$button>\n</$reveal>\n<$reveal type=\"match\" state=<<plugin-disable-title>> text=\"yes\">\n<$button set=<<plugin-disable-title>> setTo=\"no\" tooltip={{$:/language/ControlPanel/Plugins/Enable/Hint}} aria-label={{$:/language/ControlPanel/Plugins/Enable/Caption}}>\n<<lingo Enable/Caption>>\n</$button>\n</$reveal>\n</div>\n</$list>\n<$set name=\"tabsList\" filter=\"[<currentTiddler>list[]] contents\">\n<$macrocall $name=\"tabs\" state=<<tabs-state-macro>> tabsList=<<tabsList>> default={{{ [enlist<tabsList>] }}} template=\"$:/core/ui/PluginInfo\"/>\n</$set>\n</div>\n</div>\n</$reveal>\n</$set>\n\\end\n\n<$macrocall $name=\"plugin-info\" type=<<plugin-type>> default-popup-state=<<default-popup-state>>/>\n"
},
"$:/core/ui/Components/tag-link": {
"title": "$:/core/ui/Components/tag-link",
"text": "<$link>\n<$set name=\"backgroundColor\" value={{!!color}}>\n<span style=<<tag-styles>> class=\"tc-tag-label\">\n<$view field=\"title\" format=\"text\"/>\n</span>\n</$set>\n</$link>"
},
"$:/core/ui/ControlPanel/Advanced": {
"title": "$:/core/ui/ControlPanel/Advanced",
"tags": "$:/tags/ControlPanel/Info",
"caption": "{{$:/language/ControlPanel/Advanced/Caption}}",
"text": "{{$:/language/ControlPanel/Advanced/Hint}}\n\n<div class=\"tc-control-panel\">\n<<tabs \"[all[shadows+tiddlers]tag[$:/tags/ControlPanel/Advanced]!has[draft.of]]\" \"$:/core/ui/ControlPanel/TiddlerFields\">>\n</div>\n"
},
"$:/core/ui/ControlPanel/Appearance": {
"title": "$:/core/ui/ControlPanel/Appearance",
"tags": "$:/tags/ControlPanel",
"caption": "{{$:/language/ControlPanel/Appearance/Caption}}",
"text": "{{$:/language/ControlPanel/Appearance/Hint}}\n\n<div class=\"tc-control-panel\">\n<<tabs \"[all[shadows+tiddlers]tag[$:/tags/ControlPanel/Appearance]!has[draft.of]]\" \"$:/core/ui/ControlPanel/Theme\">>\n</div>\n"
},
"$:/core/ui/ControlPanel/Basics": {
"title": "$:/core/ui/ControlPanel/Basics",
"tags": "$:/tags/ControlPanel/Info",
"caption": "{{$:/language/ControlPanel/Basics/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/Basics/\n\n\\define show-filter-count(filter)\n<$button class=\"tc-btn-invisible\">\n<$action-setfield $tiddler=\"$:/temp/advancedsearch\" $value=\"\"\"$filter$\"\"\"/>\n<$action-setfield $tiddler=\"$:/state/tab--1498284803\" $value=\"$:/core/ui/AdvancedSearch/Filter\"/>\n<$action-navigate $to=\"$:/AdvancedSearch\"/>\n''<$count filter=\"\"\"$filter$\"\"\"/>''\n{{$:/core/images/advanced-search-button}}\n</$button>\n\\end\n\n|<<lingo Version/Prompt>> |''<<version>>'' |\n|<$link to=\"$:/SiteTitle\"><<lingo Title/Prompt>></$link> |<$edit-text tiddler=\"$:/SiteTitle\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/SiteSubtitle\"><<lingo Subtitle/Prompt>></$link> |<$edit-text tiddler=\"$:/SiteSubtitle\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/status/UserName\"><<lingo Username/Prompt>></$link> |<$edit-text tiddler=\"$:/status/UserName\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/config/AnimationDuration\"><<lingo AnimDuration/Prompt>></$link> |<$edit-text tiddler=\"$:/config/AnimationDuration\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/DefaultTiddlers\"><<lingo DefaultTiddlers/Prompt>></$link> |<<lingo DefaultTiddlers/TopHint>><br> <$edit tag=\"textarea\" tiddler=\"$:/DefaultTiddlers\" class=\"tc-edit-texteditor\"/><br>//<<lingo DefaultTiddlers/BottomHint>>// |\n|<$link to=\"$:/language/DefaultNewTiddlerTitle\"><<lingo NewTiddler/Title/Prompt>></$link> |<$edit-text tiddler=\"$:/language/DefaultNewTiddlerTitle\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/config/NewJournal/Title\"><<lingo NewJournal/Title/Prompt>></$link> |<$edit-text tiddler=\"$:/config/NewJournal/Title\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/config/NewJournal/Text\"><<lingo NewJournal/Text/Prompt>></$link> |<$edit tiddler=\"$:/config/NewJournal/Text\" tag=\"textarea\" class=\"tc-edit-texteditor\" default=\"\"/> |\n|<$link to=\"$:/config/NewJournal/Tags\"><<lingo NewJournal/Tags/Prompt>></$link> |<$edit-text tiddler=\"$:/config/NewJournal/Tags\" default=\"\" tag=\"input\"/> |\n|<<lingo Language/Prompt>> |{{$:/snippets/minilanguageswitcher}} |\n|<<lingo Tiddlers/Prompt>> |<<show-filter-count \"[!is[system]sort[title]]\">> |\n|<<lingo Tags/Prompt>> |<<show-filter-count \"[tags[]sort[title]]\">> |\n|<<lingo SystemTiddlers/Prompt>> |<<show-filter-count \"[is[system]sort[title]]\">> |\n|<<lingo ShadowTiddlers/Prompt>> |<<show-filter-count \"[all[shadows]sort[title]]\">> |\n|<<lingo OverriddenShadowTiddlers/Prompt>> |<<show-filter-count \"[is[tiddler]is[shadow]sort[title]]\">> |\n"
},
"$:/core/ui/ControlPanel/EditorTypes": {
"title": "$:/core/ui/ControlPanel/EditorTypes",
"tags": "$:/tags/ControlPanel/Advanced",
"caption": "{{$:/language/ControlPanel/EditorTypes/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/EditorTypes/\n\n<<lingo Hint>>\n\n<table>\n<tbody>\n<tr>\n<th><<lingo Type/Caption>></th>\n<th><<lingo Editor/Caption>></th>\n</tr>\n<$list filter=\"[all[shadows+tiddlers]prefix[$:/config/EditorTypeMappings/]sort[title]]\">\n<tr>\n<td>\n<$link>\n<$list filter=\"[all[current]removeprefix[$:/config/EditorTypeMappings/]]\">\n<$text text={{!!title}}/>\n</$list>\n</$link>\n</td>\n<td>\n<$view field=\"text\"/>\n</td>\n</tr>\n</$list>\n</tbody>\n</table>\n"
},
"$:/core/ui/ControlPanel/Info": {
"title": "$:/core/ui/ControlPanel/Info",
"tags": "$:/tags/ControlPanel",
"caption": "{{$:/language/ControlPanel/Info/Caption}}",
"text": "{{$:/language/ControlPanel/Info/Hint}}\n\n<div class=\"tc-control-panel\">\n<<tabs \"[all[shadows+tiddlers]tag[$:/tags/ControlPanel/Info]!has[draft.of]]\" \"$:/core/ui/ControlPanel/Basics\">>\n</div>\n"
},
"$:/core/ui/ControlPanel/KeyboardShortcuts": {
"title": "$:/core/ui/ControlPanel/KeyboardShortcuts",
"tags": "$:/tags/ControlPanel",
"caption": "{{$:/language/ControlPanel/KeyboardShortcuts/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/KeyboardShortcuts/\n\n\\define new-shortcut(title)\n<div class=\"tc-dropdown-item-plain\">\n<$edit-shortcut tiddler=\"$title$\" placeholder={{$:/language/ControlPanel/KeyboardShortcuts/Add/Prompt}} style=\"width:auto;\"/> <$button>\n<<lingo Add/Caption>>\n<$action-listops\n\t$tiddler=\"$(shortcutTitle)$\"\n\t$field=\"text\"\n\t$subfilter=\"[{$title$}]\"\n/>\n<$action-deletetiddler\n\t$tiddler=\"$title$\"\n/>\n</$button>\n</div>\n\\end\n\n\\define shortcut-list-item(caption)\n<td>\n</td>\n<td style=\"text-align:right;font-size:0.7em;\">\n<<lingo Platform/$caption$>>\n</td>\n<td>\n<div style=\"position:relative;\">\n<$button popup=<<qualify \"$:/state/dropdown/$(shortcutTitle)$\">> class=\"tc-btn-invisible\">\n{{$:/core/images/edit-button}}\n</$button>\n<$macrocall $name=\"displayshortcuts\" $output=\"text/html\" shortcuts={{$(shortcutTitle)$}} prefix=\"<kbd>\" separator=\"</kbd> <kbd>\" suffix=\"</kbd>\"/>\n\n<$reveal state=<<qualify \"$:/state/dropdown/$(shortcutTitle)$\">> type=\"popup\" position=\"below\" animate=\"yes\">\n<div class=\"tc-block-dropdown-wrapper\">\n<div class=\"tc-block-dropdown tc-edit-type-dropdown tc-popup-keep\">\n<$list filter=\"[list[$(shortcutTitle)$!!text]sort[title]]\" variable=\"shortcut\" emptyMessage=\"\"\"\n<div class=\"tc-dropdown-item-plain\">\n//<<lingo NoShortcuts/Caption>>//\n</div>\n\"\"\">\n<div class=\"tc-dropdown-item-plain\">\n<$button class=\"tc-btn-invisible\" tooltip=<<lingo Remove/Hint>>>\n<$action-listops\n\t$tiddler=\"$(shortcutTitle)$\"\n\t$field=\"text\"\n\t$subfilter=\"+[remove<shortcut>]\"\n/>\n×\n</$button>\n<kbd>\n<$macrocall $name=\"displayshortcuts\" $output=\"text/html\" shortcuts=<<shortcut>>/>\n</kbd>\n</div>\n</$list>\n<hr/>\n<$macrocall $name=\"new-shortcut\" title=<<qualify \"$:/state/new-shortcut/$(shortcutTitle)$\">>/>\n</div>\n</div>\n</$reveal>\n</div>\n</td>\n\\end\n\n\\define shortcut-list(caption,prefix)\n<tr>\n<$list filter=\"[[$prefix$$(shortcutName)$]]\" variable=\"shortcutTitle\">\n<<shortcut-list-item \"$caption$\">>\n</$list>\n</tr>\n\\end\n\n\\define shortcut-editor()\n<<shortcut-list \"All\" \"$:/config/shortcuts/\">>\n<<shortcut-list \"Mac\" \"$:/config/shortcuts-mac/\">>\n<<shortcut-list \"NonMac\" \"$:/config/shortcuts-not-mac/\">>\n<<shortcut-list \"Linux\" \"$:/config/shortcuts-linux/\">>\n<<shortcut-list \"NonLinux\" \"$:/config/shortcuts-not-linux/\">>\n<<shortcut-list \"Windows\" \"$:/config/shortcuts-windows/\">>\n<<shortcut-list \"NonWindows\" \"$:/config/shortcuts-not-windows/\">>\n\\end\n\n\\define shortcut-preview()\n<$macrocall $name=\"displayshortcuts\" $output=\"text/html\" shortcuts={{$(shortcutPrefix)$$(shortcutName)$}} prefix=\"<kbd>\" separator=\"</kbd> <kbd>\" suffix=\"</kbd>\"/>\n\\end\n\n\\define shortcut-item-inner()\n<tr>\n<td>\n<$reveal type=\"nomatch\" state=<<dropdownStateTitle>> text=\"open\">\n<$button class=\"tc-btn-invisible\">\n<$action-setfield\n\t$tiddler=<<dropdownStateTitle>>\n\t$value=\"open\"\n/>\n{{$:/core/images/right-arrow}}\n</$button>\n</$reveal>\n<$reveal type=\"match\" state=<<dropdownStateTitle>> text=\"open\">\n<$button class=\"tc-btn-invisible\">\n<$action-setfield\n\t$tiddler=<<dropdownStateTitle>>\n\t$value=\"close\"\n/>\n{{$:/core/images/down-arrow}}\n</$button>\n</$reveal>\n''<$text text=<<shortcutName>>/>''\n</td>\n<td>\n<$transclude tiddler=\"$:/config/ShortcutInfo/$(shortcutName)$\"/>\n</td>\n<td>\n<$list filter=\"$:/config/shortcuts/ $:/config/shortcuts-mac/ $:/config/shortcuts-not-mac/ $:/config/shortcuts-linux/ $:/config/shortcuts-not-linux/ $:/config/shortcuts-windows/ $:/config/shortcuts-not-windows/\" variable=\"shortcutPrefix\">\n<<shortcut-preview>>\n</$list>\n</td>\n</tr>\n<$set name=\"dropdownState\" value={{$(dropdownStateTitle)$}}>\n<$list filter=\"[<dropdownState>prefix[open]]\" variable=\"listItem\">\n<<shortcut-editor>>\n</$list>\n</$set>\n\\end\n\n\\define shortcut-item()\n<$set name=\"dropdownStateTitle\" value=<<qualify \"$:/state/dropdown/keyboardshortcut/$(shortcutName)$\">>>\n<<shortcut-item-inner>>\n</$set>\n\\end\n\n<table>\n<tbody>\n<$list filter=\"[all[shadows+tiddlers]removeprefix[$:/config/ShortcutInfo/]]\" variable=\"shortcutName\">\n<<shortcut-item>>\n</$list>\n</tbody>\n</table>\n"
},
"$:/core/ui/ControlPanel/LoadedModules": {
"title": "$:/core/ui/ControlPanel/LoadedModules",
"tags": "$:/tags/ControlPanel/Advanced",
"caption": "{{$:/language/ControlPanel/LoadedModules/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/\n<<lingo LoadedModules/Hint>>\n\n{{$:/snippets/modules}}\n"
},
"$:/core/ui/ControlPanel/Modals/AddPlugins": {
"title": "$:/core/ui/ControlPanel/Modals/AddPlugins",
"subtitle": "{{$:/core/images/download-button}} {{$:/language/ControlPanel/Plugins/Add/Caption}}",
"text": "\\define install-plugin-button()\n<$button>\n<$action-sendmessage $message=\"tm-load-plugin-from-library\" url={{!!url}} title={{$(assetInfo)$!!original-title}}/>\n<$list filter=\"[<assetInfo>get[original-title]get[version]]\" variable=\"installedVersion\" emptyMessage=\"\"\"{{$:/language/ControlPanel/Plugins/Install/Caption}}\"\"\">\n{{$:/language/ControlPanel/Plugins/Reinstall/Caption}}\n</$list>\n</$button>\n\\end\n\n\\define popup-state-macro()\n$:/state/add-plugin-info/$(connectionTiddler)$/$(assetInfo)$\n\\end\n\n\\define display-plugin-info(type)\n<$set name=\"popup-state\" value=<<popup-state-macro>>>\n<div class=\"tc-plugin-info\">\n<div class=\"tc-plugin-info-chunk tc-small-icon\">\n<$reveal type=\"nomatch\" state=<<popup-state>> text=\"yes\">\n<$button class=\"tc-btn-invisible tc-btn-dropdown\" set=<<popup-state>> setTo=\"yes\">\n{{$:/core/images/right-arrow}}\n</$button>\n</$reveal>\n<$reveal type=\"match\" state=<<popup-state>> text=\"yes\">\n<$button class=\"tc-btn-invisible tc-btn-dropdown\" set=<<popup-state>> setTo=\"no\">\n{{$:/core/images/down-arrow}}\n</$button>\n</$reveal>\n</div>\n<div class=\"tc-plugin-info-chunk\">\n<$list filter=\"[<assetInfo>has[icon]]\" emptyMessage=\"\"\"<$transclude tiddler=\"$:/core/images/plugin-generic-$type$\"/>\"\"\">\n<img src={{$(assetInfo)$!!icon}}/>\n</$list>\n</div>\n<div class=\"tc-plugin-info-chunk\">\n<h1><$view tiddler=<<assetInfo>> field=\"description\"/></h1>\n<h2><$view tiddler=<<assetInfo>> field=\"original-title\"/></h2>\n<div><em><$view tiddler=<<assetInfo>> field=\"version\"/></em></div>\n</div>\n<div class=\"tc-plugin-info-chunk\">\n<<install-plugin-button>>\n</div>\n</div>\n<$reveal type=\"match\" text=\"yes\" state=<<popup-state>>>\n<div class=\"tc-plugin-info-dropdown\">\n<div class=\"tc-plugin-info-dropdown-message\">\n<$list filter=\"[<assetInfo>get[original-title]get[version]]\" variable=\"installedVersion\" emptyMessage=\"\"\"{{$:/language/ControlPanel/Plugins/NotInstalled/Hint}}\"\"\">\n<em>\n{{$:/language/ControlPanel/Plugins/AlreadyInstalled/Hint}}\n</em>\n</$list>\n</div>\n<div class=\"tc-plugin-info-dropdown-body\">\n<$transclude tiddler=<<assetInfo>> field=\"readme\" mode=\"block\"/>\n</div>\n</div>\n</$reveal>\n</$set>\n\\end\n\n\\define load-plugin-library-button()\n<$button class=\"tc-btn-big-green\">\n<$action-sendmessage $message=\"tm-load-plugin-library\" url={{!!url}} infoTitlePrefix=\"$:/temp/RemoteAssetInfo/\"/>\n{{$:/core/images/chevron-right}} {{$:/language/ControlPanel/Plugins/OpenPluginLibrary}}\n</$button>\n\\end\n\n\\define display-server-assets(type)\n{{$:/language/Search/Search}}: <$edit-text tiddler=\"\"\"$:/temp/RemoteAssetSearch/$(currentTiddler)$\"\"\" default=\"\" type=\"search\" tag=\"input\"/>\n<$reveal state=\"\"\"$:/temp/RemoteAssetSearch/$(currentTiddler)$\"\"\" type=\"nomatch\" text=\"\">\n<$button class=\"tc-btn-invisible\">\n<$action-setfield $tiddler=\"\"\"$:/temp/RemoteAssetSearch/$(currentTiddler)$\"\"\" $field=\"text\" $value=\"\"/>\n{{$:/core/images/close-button}}\n</$button>\n</$reveal>\n<div class=\"tc-plugin-library-listing\">\n<$list filter=\"[all[tiddlers+shadows]tag[$:/tags/RemoteAssetInfo]server-url{!!url}original-plugin-type[$type$]search{$:/temp/RemoteAssetSearch/$(currentTiddler)$}sort[description]]\" variable=\"assetInfo\">\n<<display-plugin-info \"$type$\">>\n</$list>\n</div>\n\\end\n\n\\define display-server-connection()\n<$list filter=\"[all[tiddlers+shadows]tag[$:/tags/ServerConnection]suffix{!!url}]\" variable=\"connectionTiddler\" emptyMessage=<<load-plugin-library-button>>>\n\n<<tabs \"[[$:/core/ui/ControlPanel/Plugins/Add/Plugins]] [[$:/core/ui/ControlPanel/Plugins/Add/Themes]] [[$:/core/ui/ControlPanel/Plugins/Add/Languages]]\" \"$:/core/ui/ControlPanel/Plugins/Add/Plugins\">>\n\n</$list>\n\\end\n\n\\define close-library-button()\n<$reveal type='nomatch' state='$:/temp/ServerConnection/$(PluginLibraryURL)$' text=''>\n<$button class='tc-btn-big-green'>\n<$action-sendmessage $message=\"tm-unload-plugin-library\" url={{!!url}}/>\n{{$:/core/images/chevron-left}} {{$:/language/ControlPanel/Plugins/ClosePluginLibrary}}\n<$action-deletetiddler $filter=\"[prefix[$:/temp/ServerConnection/$(PluginLibraryURL)$]][prefix[$:/temp/RemoteAssetInfo/$(PluginLibraryURL)$]]\"/>\n</$button>\n</$reveal>\n\\end\n\n\\define plugin-library-listing()\n<$list filter=\"[all[tiddlers+shadows]tag[$:/tags/PluginLibrary]]\">\n<div class=\"tc-plugin-library\">\n\n!! <$link><$transclude field=\"caption\"><$view field=\"title\"/></$transclude></$link>\n\n//<$view field=\"url\"/>//\n\n<$transclude/>\n\n<$set name=PluginLibraryURL value={{!!url}}>\n<<close-library-button>>\n</$set>\n\n<<display-server-connection>>\n</div>\n</$list>\n\\end\n\n\\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]\n\n<div>\n<<plugin-library-listing>>\n</div>\n"
},
"$:/core/ui/ControlPanel/Palette": {
"title": "$:/core/ui/ControlPanel/Palette",
"tags": "$:/tags/ControlPanel/Appearance",
"caption": "{{$:/language/ControlPanel/Palette/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/Palette/\n\n{{$:/snippets/paletteswitcher}}\n\n<$reveal type=\"nomatch\" state=\"$:/state/ShowPaletteEditor\" text=\"yes\">\n\n<$button set=\"$:/state/ShowPaletteEditor\" setTo=\"yes\"><<lingo ShowEditor/Caption>></$button>\n\n</$reveal>\n\n<$reveal type=\"match\" state=\"$:/state/ShowPaletteEditor\" text=\"yes\">\n\n<$button set=\"$:/state/ShowPaletteEditor\" setTo=\"no\"><<lingo HideEditor/Caption>></$button>\n{{$:/snippets/paletteeditor}}\n\n</$reveal>\n\n"
},
"$:/core/ui/ControlPanel/Parsing": {
"title": "$:/core/ui/ControlPanel/Parsing",
"tags": "$:/tags/ControlPanel/Advanced",
"caption": "{{$:/language/ControlPanel/Parsing/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/Parsing/\n\n\\define toggle(Type)\n<$checkbox\ntiddler=\"\"\"$:/config/WikiParserRules/$Type$/$(rule)$\"\"\"\nfield=\"text\"\nchecked=\"enable\"\nunchecked=\"disable\"\ndefault=\"enable\">\n<<rule>>\n</$checkbox>\n\\end\n\n\\define rules(type,Type)\n<$list filter=\"[wikiparserrules[$type$]]\" variable=\"rule\">\n<dd><<toggle $Type$>></dd>\n</$list>\n\\end\n\n<<lingo Hint>>\n\n<dl>\n<dt><<lingo Pragma/Caption>></dt>\n<<rules pragma Pragma>>\n<dt><<lingo Inline/Caption>></dt>\n<<rules inline Inline>>\n<dt><<lingo Block/Caption>></dt>\n<<rules block Block>>\n</dl>"
},
"$:/core/ui/ControlPanel/Plugins/Add/Languages": {
"title": "$:/core/ui/ControlPanel/Plugins/Add/Languages",
"caption": "{{$:/language/ControlPanel/Plugins/Languages/Caption}} (<$count filter=\"[all[tiddlers+shadows]tag[$:/tags/RemoteAssetInfo]server-url{!!url}original-plugin-type[language]]\"/>)",
"text": "<<display-server-assets language>>\n"
},
"$:/core/ui/ControlPanel/Plugins/Add/Plugins": {
"title": "$:/core/ui/ControlPanel/Plugins/Add/Plugins",
"caption": "{{$:/language/ControlPanel/Plugins/Plugins/Caption}} (<$count filter=\"[all[tiddlers+shadows]tag[$:/tags/RemoteAssetInfo]server-url{!!url}original-plugin-type[plugin]]\"/>)",
"text": "<<display-server-assets plugin>>\n"
},
"$:/core/ui/ControlPanel/Plugins/Add/Themes": {
"title": "$:/core/ui/ControlPanel/Plugins/Add/Themes",
"caption": "{{$:/language/ControlPanel/Plugins/Themes/Caption}} (<$count filter=\"[all[tiddlers+shadows]tag[$:/tags/RemoteAssetInfo]server-url{!!url}original-plugin-type[theme]]\"/>)",
"text": "<<display-server-assets theme>>\n"
},
"$:/core/ui/ControlPanel/Plugins/AddPlugins": {
"title": "$:/core/ui/ControlPanel/Plugins/AddPlugins",
"text": "\\define lingo-base() $:/language/ControlPanel/Plugins/\n\n<$button message=\"tm-modal\" param=\"$:/core/ui/ControlPanel/Modals/AddPlugins\" tooltip={{$:/language/ControlPanel/Plugins/Add/Hint}} class=\"tc-btn-big-green\" style=\"background:blue;\">\n{{$:/core/images/download-button}} <<lingo Add/Caption>>\n</$button>\n"
},
"$:/core/ui/ControlPanel/Plugins/Installed/Languages": {
"title": "$:/core/ui/ControlPanel/Plugins/Installed/Languages",
"caption": "{{$:/language/ControlPanel/Plugins/Languages/Caption}} (<$count filter=\"[!has[draft.of]plugin-type[language]]\"/>)",
"text": "<<plugin-table language>>\n"
},
"$:/core/ui/ControlPanel/Plugins/Installed/Plugins": {
"title": "$:/core/ui/ControlPanel/Plugins/Installed/Plugins",
"caption": "{{$:/language/ControlPanel/Plugins/Plugins/Caption}} (<$count filter=\"[!has[draft.of]plugin-type[plugin]]\"/>)",
"text": "<<plugin-table plugin>>\n"
},
"$:/core/ui/ControlPanel/Plugins/Installed/Themes": {
"title": "$:/core/ui/ControlPanel/Plugins/Installed/Themes",
"caption": "{{$:/language/ControlPanel/Plugins/Themes/Caption}} (<$count filter=\"[!has[draft.of]plugin-type[theme]]\"/>)",
"text": "<<plugin-table theme>>\n"
},
"$:/core/ui/ControlPanel/Plugins": {
"title": "$:/core/ui/ControlPanel/Plugins",
"tags": "$:/tags/ControlPanel",
"caption": "{{$:/language/ControlPanel/Plugins/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/Plugins/\n\n\\define plugin-table(type)\n<$set name=\"plugin-type\" value=\"\"\"$type$\"\"\">\n<$set name=\"qualified-state\" value=<<qualify \"$:/state/plugin-info\">>>\n<$list filter=\"[!has[draft.of]plugin-type[$type$]sort[description]]\" emptyMessage=<<lingo \"Empty/Hint\">> template=\"$:/core/ui/Components/plugin-info\"/>\n</$set>\n</$set>\n\\end\n\n{{$:/core/ui/ControlPanel/Plugins/AddPlugins}}\n\n<<lingo Installed/Hint>>\n\n<<tabs \"[[$:/core/ui/ControlPanel/Plugins/Installed/Plugins]] [[$:/core/ui/ControlPanel/Plugins/Installed/Themes]] [[$:/core/ui/ControlPanel/Plugins/Installed/Languages]]\" \"$:/core/ui/ControlPanel/Plugins/Installed/Plugins\">>\n"
},
"$:/core/ui/ControlPanel/Saving/DownloadSaver": {
"title": "$:/core/ui/ControlPanel/Saving/DownloadSaver",
"tags": "$:/tags/ControlPanel/Saving",
"caption": "{{$:/language/ControlPanel/Saving/DownloadSaver/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/Saving/DownloadSaver/\n\n<<lingo Hint>>\n\n!! <$link to=\"$:/config/DownloadSaver/AutoSave\"><<lingo AutoSave/Hint>></$link>\n\n<$checkbox tiddler=\"$:/config/DownloadSaver/AutoSave\" field=\"text\" checked=\"yes\" unchecked=\"no\" default=\"no\"> <<lingo AutoSave/Description>> </$checkbox>\n"
},
"$:/core/ui/ControlPanel/Saving/General": {
"title": "$:/core/ui/ControlPanel/Saving/General",
"tags": "$:/tags/ControlPanel/Saving",
"caption": "{{$:/language/ControlPanel/Saving/General/Caption}}",
"list-before": "",
"text": "\\define lingo-base() $:/language/ControlPanel/Settings/\n\n{{$:/language/ControlPanel/Saving/General/Hint}}\n\n!! <$link to=\"$:/config/AutoSave\"><<lingo AutoSave/Caption>></$link>\n\n<<lingo AutoSave/Hint>>\n\n<$radio tiddler=\"$:/config/AutoSave\" value=\"yes\"> <<lingo AutoSave/Enabled/Description>> </$radio>\n\n<$radio tiddler=\"$:/config/AutoSave\" value=\"no\"> <<lingo AutoSave/Disabled/Description>> </$radio>\n"
},
"$:/core/ui/ControlPanel/Saving/TiddlySpot": {
"title": "$:/core/ui/ControlPanel/Saving/TiddlySpot",
"tags": "$:/tags/ControlPanel/Saving",
"caption": "{{$:/language/ControlPanel/Saving/TiddlySpot/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/Saving/TiddlySpot/\n\n\\define backupURL()\nhttp://$(userName)$.tiddlyspot.com/backup/\n\\end\n\\define backupLink()\n<$reveal type=\"nomatch\" state=\"$:/UploadName\" text=\"\">\n<$set name=\"userName\" value={{$:/UploadName}}>\n<$reveal type=\"match\" state=\"$:/UploadURL\" text=\"\">\n<<backupURL>>\n</$reveal>\n<$reveal type=\"nomatch\" state=\"$:/UploadURL\" text=\"\">\n<$macrocall $name=resolvePath source={{$:/UploadBackupDir}} root={{$:/UploadURL}}>>\n</$reveal>\n</$set>\n</$reveal>\n\\end\n\n<<lingo Description>>\n\n|<<lingo UserName>> |<$edit-text tiddler=\"$:/UploadName\" default=\"\" tag=\"input\"/> |\n|<<lingo Password>> |<$password name=\"upload\"/> |\n|<<lingo Backups>> |<<backupLink>> |\n\n''<<lingo Advanced/Heading>>''\n\n|<<lingo ServerURL>> |<$edit-text tiddler=\"$:/UploadURL\" default=\"\" tag=\"input\"/> |\n|<<lingo Filename>> |<$edit-text tiddler=\"$:/UploadFilename\" default=\"index.html\" tag=\"input\"/> |\n|<<lingo UploadDir>> |<$edit-text tiddler=\"$:/UploadDir\" default=\".\" tag=\"input\"/> |\n|<<lingo BackupDir>> |<$edit-text tiddler=\"$:/UploadBackupDir\" default=\".\" tag=\"input\"/> |\n\n<<lingo TiddlySpot/Hint>>"
},
"$:/core/ui/ControlPanel/Saving": {
"title": "$:/core/ui/ControlPanel/Saving",
"tags": "$:/tags/ControlPanel",
"caption": "{{$:/language/ControlPanel/Saving/Caption}}",
"text": "{{$:/language/ControlPanel/Saving/Hint}}\n\n<div class=\"tc-control-panel\">\n<<tabs \"[all[shadows+tiddlers]tag[$:/tags/ControlPanel/Saving]!has[draft.of]]\" \"$:/core/ui/ControlPanel/Saving/General\">>\n</div>\n"
},
"$:/core/buttonstyles/Borderless": {
"title": "$:/core/buttonstyles/Borderless",
"tags": "$:/tags/ToolbarButtonStyle",
"caption": "{{$:/language/ControlPanel/Settings/ToolbarButtonStyle/Styles/Borderless}}",
"text": "tc-btn-invisible"
},
"$:/core/buttonstyles/Boxed": {
"title": "$:/core/buttonstyles/Boxed",
"tags": "$:/tags/ToolbarButtonStyle",
"caption": "{{$:/language/ControlPanel/Settings/ToolbarButtonStyle/Styles/Boxed}}",
"text": "tc-btn-boxed"
},
"$:/core/buttonstyles/Rounded": {
"title": "$:/core/buttonstyles/Rounded",
"tags": "$:/tags/ToolbarButtonStyle",
"caption": "{{$:/language/ControlPanel/Settings/ToolbarButtonStyle/Styles/Rounded}}",
"text": "tc-btn-rounded"
},
"$:/core/ui/ControlPanel/Settings/CamelCase": {
"title": "$:/core/ui/ControlPanel/Settings/CamelCase",
"tags": "$:/tags/ControlPanel/Settings",
"caption": "{{$:/language/ControlPanel/Settings/CamelCase/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/Settings/CamelCase/\n<<lingo Hint>>\n\n<$checkbox tiddler=\"$:/config/WikiParserRules/Inline/wikilink\" field=\"text\" checked=\"enable\" unchecked=\"disable\" default=\"enable\"> <$link to=\"$:/config/WikiParserRules/Inline/wikilink\"><<lingo Description>></$link> </$checkbox>\n"
},
"$:/core/ui/ControlPanel/Settings/DefaultMoreSidebarTab": {
"title": "$:/core/ui/ControlPanel/Settings/DefaultMoreSidebarTab",
"caption": "{{$:/language/ControlPanel/Settings/DefaultMoreSidebarTab/Caption}}",
"tags": "$:/tags/ControlPanel/Settings",
"text": "\\define lingo-base() $:/language/ControlPanel/Settings/DefaultMoreSidebarTab/\n\n<$link to=\"$:/config/DefaultMoreSidebarTab\"><<lingo Hint>></$link>\n\n<$select tiddler=\"$:/config/DefaultMoreSidebarTab\">\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/MoreSideBar]!has[draft.of]]\">\n<option value=<<currentTiddler>>><$transclude field=\"caption\"><$text text=<<currentTiddler>>/></$transclude></option>\n</$list>\n</$select>\n"
},
"$:/core/ui/ControlPanel/Settings/DefaultSidebarTab": {
"title": "$:/core/ui/ControlPanel/Settings/DefaultSidebarTab",
"caption": "{{$:/language/ControlPanel/Settings/DefaultSidebarTab/Caption}}",
"tags": "$:/tags/ControlPanel/Settings",
"text": "\\define lingo-base() $:/language/ControlPanel/Settings/DefaultSidebarTab/\n\n<$link to=\"$:/config/DefaultSidebarTab\"><<lingo Hint>></$link>\n\n<$select tiddler=\"$:/config/DefaultSidebarTab\">\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/SideBar]!has[draft.of]]\">\n<option value=<<currentTiddler>>><$transclude field=\"caption\"><$text text=<<currentTiddler>>/></$transclude></option>\n</$list>\n</$select>\n"
},
"$:/core/ui/ControlPanel/Settings/EditorToolbar": {
"title": "$:/core/ui/ControlPanel/Settings/EditorToolbar",
"tags": "$:/tags/ControlPanel/Settings",
"caption": "{{$:/language/ControlPanel/Settings/EditorToolbar/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/Settings/EditorToolbar/\n<<lingo Hint>>\n\n<$checkbox tiddler=\"$:/config/TextEditor/EnableToolbar\" field=\"text\" checked=\"yes\" unchecked=\"no\" default=\"yes\"> <$link to=\"$:/config/TextEditor/EnableToolbar\"><<lingo Description>></$link> </$checkbox>\n\n"
},
"$:/core/ui/ControlPanel/Settings/InfoPanelMode": {
"title": "$:/core/ui/ControlPanel/Settings/InfoPanelMode",
"tags": "$:/tags/ControlPanel/Settings",
"caption": "{{$:/language/ControlPanel/Settings/InfoPanelMode/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/Settings/InfoPanelMode/\n<$link to=\"$:/config/TiddlerInfo/Mode\"><<lingo Hint>></$link>\n\n<$radio tiddler=\"$:/config/TiddlerInfo/Mode\" value=\"popup\"> <<lingo Popup/Description>> </$radio>\n\n<$radio tiddler=\"$:/config/TiddlerInfo/Mode\" value=\"sticky\"> <<lingo Sticky/Description>> </$radio>\n"
},
"$:/core/ui/ControlPanel/Settings/LinkToBehaviour": {
"title": "$:/core/ui/ControlPanel/Settings/LinkToBehaviour",
"tags": "$:/tags/ControlPanel/Settings",
"caption": "{{$:/language/ControlPanel/Settings/LinkToBehaviour/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/Settings/LinkToBehaviour/\n\n<$link to=\"$:/config/Navigation/openLinkFromInsideRiver\"><<lingo \"InsideRiver/Hint\">></$link>\n\n<$select tiddler=\"$:/config/Navigation/openLinkFromInsideRiver\">\n <option value=\"above\"><<lingo \"OpenAbove\">></option>\n <option value=\"below\"><<lingo \"OpenBelow\">></option>\n <option value=\"top\"><<lingo \"OpenAtTop\">></option>\n <option value=\"bottom\"><<lingo \"OpenAtBottom\">></option>\n</$select>\n\n<$link to=\"$:/config/Navigation/openLinkFromOutsideRiver\"><<lingo \"OutsideRiver/Hint\">></$link>\n\n<$select tiddler=\"$:/config/Navigation/openLinkFromOutsideRiver\">\n <option value=\"top\"><<lingo \"OpenAtTop\">></option>\n <option value=\"bottom\"><<lingo \"OpenAtBottom\">></option>\n</$select>\n"
},
"$:/core/ui/ControlPanel/Settings/MissingLinks": {
"title": "$:/core/ui/ControlPanel/Settings/MissingLinks",
"tags": "$:/tags/ControlPanel/Settings",
"caption": "{{$:/language/ControlPanel/Settings/MissingLinks/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/Settings/MissingLinks/\n<<lingo Hint>>\n\n<$checkbox tiddler=\"$:/config/MissingLinks\" field=\"text\" checked=\"yes\" unchecked=\"no\" default=\"yes\"> <$link to=\"$:/config/MissingLinks\"><<lingo Description>></$link> </$checkbox>\n\n"
},
"$:/core/ui/ControlPanel/Settings/NavigationAddressBar": {
"title": "$:/core/ui/ControlPanel/Settings/NavigationAddressBar",
"tags": "$:/tags/ControlPanel/Settings",
"caption": "{{$:/language/ControlPanel/Settings/NavigationAddressBar/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/Settings/NavigationAddressBar/\n\n<$link to=\"$:/config/Navigation/UpdateAddressBar\"><<lingo Hint>></$link>\n\n<$radio tiddler=\"$:/config/Navigation/UpdateAddressBar\" value=\"permaview\"> <<lingo Permaview/Description>> </$radio>\n\n<$radio tiddler=\"$:/config/Navigation/UpdateAddressBar\" value=\"permalink\"> <<lingo Permalink/Description>> </$radio>\n\n<$radio tiddler=\"$:/config/Navigation/UpdateAddressBar\" value=\"no\"> <<lingo No/Description>> </$radio>\n"
},
"$:/core/ui/ControlPanel/Settings/NavigationHistory": {
"title": "$:/core/ui/ControlPanel/Settings/NavigationHistory",
"tags": "$:/tags/ControlPanel/Settings",
"caption": "{{$:/language/ControlPanel/Settings/NavigationHistory/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/Settings/NavigationHistory/\n<$link to=\"$:/config/Navigation/UpdateHistory\"><<lingo Hint>></$link>\n\n<$radio tiddler=\"$:/config/Navigation/UpdateHistory\" value=\"yes\"> <<lingo Yes/Description>> </$radio>\n\n<$radio tiddler=\"$:/config/Navigation/UpdateHistory\" value=\"no\"> <<lingo No/Description>> </$radio>\n"
},
"$:/core/ui/ControlPanel/Settings/NavigationPermalinkviewMode": {
"title": "$:/core/ui/ControlPanel/Settings/NavigationPermalinkviewMode",
"tags": "$:/tags/ControlPanel/Settings",
"caption": "{{$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/Settings/NavigationPermalinkviewMode/\n<<lingo Hint>>\n\n<$checkbox tiddler=\"$:/config/Navigation/Permalinkview/CopyToClipboard\" field=\"text\" checked=\"yes\" unchecked=\"no\" default=\"yes\"> <$link to=\"$:/config/Navigation/Permalinkview/CopyToClipboard\"><<lingo CopyToClipboard/Description>></$link> </$checkbox>\n\n<$checkbox tiddler=\"$:/config/Navigation/Permalinkview/UpdateAddressBar\" field=\"text\" checked=\"yes\" unchecked=\"no\" default=\"yes\"> <$link to=\"$:/config/Navigation/Permalinkview/UpdateAddressBar\"><<lingo UpdateAddressBar/Description>></$link> </$checkbox>\n"
},
"$:/core/ui/ControlPanel/Settings/PerformanceInstrumentation": {
"title": "$:/core/ui/ControlPanel/Settings/PerformanceInstrumentation",
"tags": "$:/tags/ControlPanel/Settings",
"caption": "{{$:/language/ControlPanel/Settings/PerformanceInstrumentation/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/Settings/PerformanceInstrumentation/\n<<lingo Hint>>\n\n<$checkbox tiddler=\"$:/config/Performance/Instrumentation\" field=\"text\" checked=\"yes\" unchecked=\"no\" default=\"no\"> <$link to=\"$:/config/Performance/Instrumentation\"><<lingo Description>></$link> </$checkbox>\n"
},
"$:/core/ui/ControlPanel/Settings/TitleLinks": {
"title": "$:/core/ui/ControlPanel/Settings/TitleLinks",
"tags": "$:/tags/ControlPanel/Settings",
"caption": "{{$:/language/ControlPanel/Settings/TitleLinks/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/Settings/TitleLinks/\n<$link to=\"$:/config/Tiddlers/TitleLinks\"><<lingo Hint>></$link>\n\n<$radio tiddler=\"$:/config/Tiddlers/TitleLinks\" value=\"yes\"> <<lingo Yes/Description>> </$radio>\n\n<$radio tiddler=\"$:/config/Tiddlers/TitleLinks\" value=\"no\"> <<lingo No/Description>> </$radio>\n"
},
"$:/core/ui/ControlPanel/Settings/ToolbarButtonStyle": {
"title": "$:/core/ui/ControlPanel/Settings/ToolbarButtonStyle",
"tags": "$:/tags/ControlPanel/Settings",
"caption": "{{$:/language/ControlPanel/Settings/ToolbarButtonStyle/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/Settings/ToolbarButtonStyle/\n<$link to=\"$:/config/Toolbar/ButtonClass\"><<lingo \"Hint\">></$link>\n\n<$select tiddler=\"$:/config/Toolbar/ButtonClass\">\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/ToolbarButtonStyle]]\">\n<option value={{!!text}}>{{!!caption}}</option>\n</$list>\n</$select>\n"
},
"$:/core/ui/ControlPanel/Settings/ToolbarButtons": {
"title": "$:/core/ui/ControlPanel/Settings/ToolbarButtons",
"tags": "$:/tags/ControlPanel/Settings",
"caption": "{{$:/language/ControlPanel/Settings/ToolbarButtons/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/Settings/ToolbarButtons/\n<<lingo Hint>>\n\n<$checkbox tiddler=\"$:/config/Toolbar/Icons\" field=\"text\" checked=\"yes\" unchecked=\"no\" default=\"yes\"> <$link to=\"$:/config/Toolbar/Icons\"><<lingo Icons/Description>></$link> </$checkbox>\n\n<$checkbox tiddler=\"$:/config/Toolbar/Text\" field=\"text\" checked=\"yes\" unchecked=\"no\" default=\"no\"> <$link to=\"$:/config/Toolbar/Text\"><<lingo Text/Description>></$link> </$checkbox>\n"
},
"$:/core/ui/ControlPanel/Settings": {
"title": "$:/core/ui/ControlPanel/Settings",
"tags": "$:/tags/ControlPanel",
"caption": "{{$:/language/ControlPanel/Settings/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/Settings/\n\n<<lingo Hint>>\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/ControlPanel/Settings]]\">\n\n<div style=\"border-top:1px solid #eee;\">\n\n!! <$link><$transclude field=\"caption\"/></$link>\n\n<$transclude/>\n\n</div>\n\n</$list>\n"
},
"$:/core/ui/ControlPanel/StoryView": {
"title": "$:/core/ui/ControlPanel/StoryView",
"tags": "$:/tags/ControlPanel/Appearance",
"caption": "{{$:/language/ControlPanel/StoryView/Caption}}",
"text": "{{$:/snippets/viewswitcher}}\n"
},
"$:/core/ui/ControlPanel/Stylesheets": {
"title": "$:/core/ui/ControlPanel/Stylesheets",
"tags": "$:/tags/ControlPanel/Advanced",
"caption": "{{$:/language/ControlPanel/Stylesheets/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/\n\n<<lingo Stylesheets/Hint>>\n\n{{$:/snippets/peek-stylesheets}}\n"
},
"$:/core/ui/ControlPanel/Theme": {
"title": "$:/core/ui/ControlPanel/Theme",
"tags": "$:/tags/ControlPanel/Appearance",
"caption": "{{$:/language/ControlPanel/Theme/Caption}}",
"text": "{{$:/snippets/themeswitcher}}\n"
},
"$:/core/ui/ControlPanel/TiddlerFields": {
"title": "$:/core/ui/ControlPanel/TiddlerFields",
"tags": "$:/tags/ControlPanel/Advanced",
"caption": "{{$:/language/ControlPanel/TiddlerFields/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/\n\n<<lingo TiddlerFields/Hint>>\n\n{{$:/snippets/allfields}}"
},
"$:/core/ui/ControlPanel/Toolbars/EditToolbar": {
"title": "$:/core/ui/ControlPanel/Toolbars/EditToolbar",
"tags": "$:/tags/ControlPanel/Toolbars",
"caption": "{{$:/language/ControlPanel/Toolbars/EditToolbar/Caption}}",
"text": "\\define lingo-base() $:/language/TiddlerInfo/\n\n\\define config-base() $:/config/EditToolbarButtons/Visibility/\n\n{{$:/language/ControlPanel/Toolbars/EditToolbar/Hint}}\n\n<$set name=\"tv-config-toolbar-icons\" value=\"yes\">\n\n<$set name=\"tv-config-toolbar-text\" value=\"yes\">\n\n<$macrocall $name=\"list-tagged-draggable\" tag=\"$:/tags/EditToolbar\" itemTemplate=\"$:/core/ui/ControlPanel/Toolbars/ItemTemplate\"/>\n\n</$set>\n\n</$set>"
},
"$:/core/ui/ControlPanel/Toolbars/EditorItemTemplate": {
"title": "$:/core/ui/ControlPanel/Toolbars/EditorItemTemplate",
"text": "\\define config-title()\n$(config-base)$$(currentTiddler)$\n\\end\n\n<$draggable tiddler=<<currentTiddler>>>\n<$checkbox tiddler=<<config-title>> field=\"text\" checked=\"show\" unchecked=\"hide\" default=\"show\"/> <span class=\"tc-icon-wrapper\"><$transclude tiddler={{!!icon}}/></span> <$transclude field=\"caption\"/> -- <i class=\"tc-muted\"><$transclude field=\"description\"/></i>\n</$draggable>\n"
},
"$:/core/ui/ControlPanel/Toolbars/EditorToolbar": {
"title": "$:/core/ui/ControlPanel/Toolbars/EditorToolbar",
"tags": "$:/tags/ControlPanel/Toolbars",
"caption": "{{$:/language/ControlPanel/Toolbars/EditorToolbar/Caption}}",
"text": "\\define lingo-base() $:/language/TiddlerInfo/\n\n\\define config-base() $:/config/EditorToolbarButtons/Visibility/\n\n{{$:/language/ControlPanel/Toolbars/EditorToolbar/Hint}}\n\n<$macrocall $name=\"list-tagged-draggable\" tag=\"$:/tags/EditorToolbar\" itemTemplate=\"$:/core/ui/ControlPanel/Toolbars/EditorItemTemplate\"/>\n"
},
"$:/core/ui/ControlPanel/Toolbars/ItemTemplate": {
"title": "$:/core/ui/ControlPanel/Toolbars/ItemTemplate",
"text": "\\define config-title()\n$(config-base)$$(currentTiddler)$\n\\end\n\n<$draggable tiddler=<<currentTiddler>>>\n<$checkbox tiddler=<<config-title>> field=\"text\" checked=\"show\" unchecked=\"hide\" default=\"show\"/> <span class=\"tc-icon-wrapper\"> <$transclude field=\"caption\"/> <i class=\"tc-muted\">-- <$transclude field=\"description\"/></i></span>\n</$draggable>\n"
},
"$:/core/ui/ControlPanel/Toolbars/PageControls": {
"title": "$:/core/ui/ControlPanel/Toolbars/PageControls",
"tags": "$:/tags/ControlPanel/Toolbars",
"caption": "{{$:/language/ControlPanel/Toolbars/PageControls/Caption}}",
"text": "\\define lingo-base() $:/language/TiddlerInfo/\n\n\\define config-base() $:/config/PageControlButtons/Visibility/\n\n{{$:/language/ControlPanel/Toolbars/PageControls/Hint}}\n\n<$set name=\"tv-config-toolbar-icons\" value=\"yes\">\n\n<$set name=\"tv-config-toolbar-text\" value=\"yes\">\n\n<$macrocall $name=\"list-tagged-draggable\" tag=\"$:/tags/PageControls\" itemTemplate=\"$:/core/ui/ControlPanel/Toolbars/ItemTemplate\"/>\n\n</$set>\n\n</$set>\n"
},
"$:/core/ui/ControlPanel/Toolbars/ViewToolbar": {
"title": "$:/core/ui/ControlPanel/Toolbars/ViewToolbar",
"tags": "$:/tags/ControlPanel/Toolbars",
"caption": "{{$:/language/ControlPanel/Toolbars/ViewToolbar/Caption}}",
"text": "\\define lingo-base() $:/language/TiddlerInfo/\n\n\\define config-base() $:/config/ViewToolbarButtons/Visibility/\n\n{{$:/language/ControlPanel/Toolbars/ViewToolbar/Hint}}\n\n<$set name=\"tv-config-toolbar-icons\" value=\"yes\">\n\n<$set name=\"tv-config-toolbar-text\" value=\"yes\">\n\n<$macrocall $name=\"list-tagged-draggable\" tag=\"$:/tags/ViewToolbar\" itemTemplate=\"$:/core/ui/ControlPanel/Toolbars/ItemTemplate\"/>\n\n</$set>\n\n</$set>\n"
},
"$:/core/ui/ControlPanel/Toolbars": {
"title": "$:/core/ui/ControlPanel/Toolbars",
"tags": "$:/tags/ControlPanel/Appearance",
"caption": "{{$:/language/ControlPanel/Toolbars/Caption}}",
"text": "{{$:/language/ControlPanel/Toolbars/Hint}}\n\n<div class=\"tc-control-panel\">\n<<tabs \"[all[shadows+tiddlers]tag[$:/tags/ControlPanel/Toolbars]!has[draft.of]]\" \"$:/core/ui/ControlPanel/Toolbars/ViewToolbar\" \"$:/state/tabs/controlpanel/toolbars\" \"tc-vertical\">>\n</div>\n"
},
"$:/ControlPanel": {
"title": "$:/ControlPanel",
"icon": "$:/core/images/options-button",
"color": "#bbb",
"text": "<div class=\"tc-control-panel\">\n<<tabs \"[all[shadows+tiddlers]tag[$:/tags/ControlPanel]!has[draft.of]]\" \"$:/core/ui/ControlPanel/Info\">>\n</div>\n"
},
"$:/core/ui/DefaultSearchResultList": {
"title": "$:/core/ui/DefaultSearchResultList",
"tags": "$:/tags/SearchResults",
"caption": "{{$:/language/Search/DefaultResults/Caption}}",
"text": "\\define searchResultList()\n//<small>{{$:/language/Search/Matches/Title}}</small>//\n\n<$list filter=\"[!is[system]search:title{$(searchTiddler)$}sort[title]limit[250]]\" template=\"$:/core/ui/ListItemTemplate\"/>\n\n//<small>{{$:/language/Search/Matches/All}}</small>//\n\n<$list filter=\"[!is[system]search{$(searchTiddler)$}sort[title]limit[250]]\" template=\"$:/core/ui/ListItemTemplate\"/>\n\n\\end\n<<searchResultList>>\n"
},
"$:/core/ui/EditTemplate/body/preview/diffs-current": {
"title": "$:/core/ui/EditTemplate/body/preview/diffs-current",
"tags": "$:/tags/EditPreview",
"caption": "differences from current",
"list-after": "$:/core/ui/EditTemplate/body/preview/output",
"text": "<$list filter=\"[<currentTiddler>!is[image]]\" emptyMessage={{$:/core/ui/EditTemplate/body/preview/output}}>\n\n<$macrocall $name=\"compareTiddlerText\" sourceTiddlerTitle={{!!draft.of}} destTiddlerTitle=<<currentTiddler>>/>\n\n</$list>\n\n"
},
"$:/core/ui/EditTemplate/body/preview/diffs-shadow": {
"title": "$:/core/ui/EditTemplate/body/preview/diffs-shadow",
"tags": "$:/tags/EditPreview",
"caption": "differences from shadow (if any)",
"list-after": "$:/core/ui/EditTemplate/body/preview/output",
"text": "<$list filter=\"[<currentTiddler>!is[image]]\" emptyMessage={{$:/core/ui/EditTemplate/body/preview/output}}>\n\n<$macrocall $name=\"compareTiddlerText\" sourceTiddlerTitle={{{ [{!!draft.of}shadowsource[]] }}} sourceSubTiddlerTitle={{!!draft.of}} destTiddlerTitle=<<currentTiddler>>/>\n\n</$list>\n\n"
},
"$:/core/ui/EditTemplate/body/preview/output": {
"title": "$:/core/ui/EditTemplate/body/preview/output",
"tags": "$:/tags/EditPreview",
"caption": "{{$:/language/EditTemplate/Body/Preview/Type/Output}}",
"text": "<$set name=\"tv-tiddler-preview\" value=\"yes\">\n\n<$transclude />\n\n</$set>\n"
},
"$:/state/showeditpreview": {
"title": "$:/state/showeditpreview",
"text": "no"
},
"$:/core/ui/EditTemplate/body/editor": {
"title": "$:/core/ui/EditTemplate/body/editor",
"text": "<$edit\n\n field=\"text\"\n class=\"tc-edit-texteditor\"\n placeholder={{$:/language/EditTemplate/Body/Placeholder}}\n\n><$set\n\n name=\"targetTiddler\"\n value=<<currentTiddler>>\n\n><$list\n\n filter=\"[all[shadows+tiddlers]tag[$:/tags/EditorToolbar]!has[draft.of]]\"\n\n><$reveal\n\n type=\"nomatch\"\n state=<<config-visibility-title>>\n text=\"hide\"\n class=\"tc-text-editor-toolbar-item-wrapper\"\n\n><$transclude\n\n tiddler=\"$:/core/ui/EditTemplate/body/toolbar/button\"\n mode=\"inline\"\n\n/></$reveal></$list></$set></$edit>\n"
},
"$:/core/ui/EditTemplate/body/toolbar/button": {
"title": "$:/core/ui/EditTemplate/body/toolbar/button",
"text": "\\define toolbar-button-icon()\n<$list\n\n filter=\"[all[current]!has[custom-icon]]\"\n variable=\"no-custom-icon\"\n\n><$transclude\n\n tiddler={{!!icon}}\n\n/></$list>\n\\end\n\n\\define toolbar-button-tooltip()\n{{!!description}}<$macrocall $name=\"displayshortcuts\" $output=\"text/plain\" shortcuts={{!!shortcuts}} prefix=\"` - [\" separator=\"] [\" suffix=\"]`\"/>\n\\end\n\n\\define toolbar-button()\n<$list\n\n filter={{!!condition}}\n variable=\"list-condition\"\n\n><$wikify\n\n name=\"tooltip-text\"\n text=<<toolbar-button-tooltip>>\n mode=\"inline\"\n output=\"text\"\n\n><$list\n\n filter=\"[all[current]!has[dropdown]]\"\n variable=\"no-dropdown\"\n\n><$button\n\n class=\"tc-btn-invisible $(buttonClasses)$\"\n tooltip=<<tooltip-text>>\n actions={{!!actions}}\n\n><span\n\n data-tw-keyboard-shortcut={{!!shortcuts}}\n\n/><<toolbar-button-icon>><$transclude\n\n tiddler=<<currentTiddler>>\n field=\"text\"\n\n/></$button></$list><$list\n\n filter=\"[all[current]has[dropdown]]\"\n variable=\"dropdown\"\n\n><$set\n\n name=\"dropdown-state\"\n value=<<qualify \"$:/state/EditorToolbarDropdown\">>\n\n><$button\n\n popup=<<dropdown-state>>\n class=\"tc-popup-keep tc-btn-invisible $(buttonClasses)$\"\n selectedClass=\"tc-selected\"\n tooltip=<<tooltip-text>>\n actions={{!!actions}}\n\n><span\n\n data-tw-keyboard-shortcut={{!!shortcuts}}\n\n/><<toolbar-button-icon>><$transclude\n\n tiddler=<<currentTiddler>>\n field=\"text\"\n\n/></$button><$reveal\n\n state=<<dropdown-state>>\n type=\"popup\"\n position=\"below\"\n animate=\"yes\"\n tag=\"span\"\n\n><div\n\n class=\"tc-drop-down tc-popup-keep\"\n\n><$transclude\n\n tiddler={{!!dropdown}}\n mode=\"block\"\n\n/></div></$reveal></$set></$list></$wikify></$list>\n\\end\n\n\\define toolbar-button-outer()\n<$set\n\n name=\"buttonClasses\"\n value={{!!button-classes}}\n\n><<toolbar-button>></$set>\n\\end\n\n<<toolbar-button-outer>>"
},
"$:/core/ui/EditTemplate/body": {
"title": "$:/core/ui/EditTemplate/body",
"tags": "$:/tags/EditTemplate",
"text": "\\define lingo-base() $:/language/EditTemplate/Body/\n\\define config-visibility-title()\n$:/config/EditorToolbarButtons/Visibility/$(currentTiddler)$\n\\end\n<$list filter=\"[all[current]has[_canonical_uri]]\">\n\n<div class=\"tc-message-box\">\n\n<<lingo External/Hint>>\n\n<a href={{!!_canonical_uri}}><$text text={{!!_canonical_uri}}/></a>\n\n<$edit-text field=\"_canonical_uri\" class=\"tc-edit-fields\"></$edit-text>\n\n</div>\n\n</$list>\n\n<$list filter=\"[all[current]!has[_canonical_uri]]\">\n\n<$reveal state=\"$:/state/showeditpreview\" type=\"match\" text=\"yes\">\n\n<div class=\"tc-tiddler-preview\">\n\n<$transclude tiddler=\"$:/core/ui/EditTemplate/body/editor\" mode=\"inline\"/>\n\n<div class=\"tc-tiddler-preview-preview\">\n\n<$transclude tiddler={{$:/state/editpreviewtype}} mode=\"inline\">\n\n<$transclude tiddler=\"$:/core/ui/EditTemplate/body/preview/output\" mode=\"inline\"/>\n\n</$transclude>\n\n</div>\n\n</div>\n\n</$reveal>\n\n<$reveal state=\"$:/state/showeditpreview\" type=\"nomatch\" text=\"yes\">\n\n<$transclude tiddler=\"$:/core/ui/EditTemplate/body/editor\" mode=\"inline\"/>\n\n</$reveal>\n\n</$list>\n"
},
"$:/core/ui/EditTemplate/controls": {
"title": "$:/core/ui/EditTemplate/controls",
"tags": "$:/tags/EditTemplate",
"text": "\\define config-title()\n$:/config/EditToolbarButtons/Visibility/$(listItem)$\n\\end\n<div class=\"tc-tiddler-title tc-tiddler-edit-title\">\n<$view field=\"title\"/>\n<span class=\"tc-tiddler-controls tc-titlebar\"><$list filter=\"[all[shadows+tiddlers]tag[$:/tags/EditToolbar]!has[draft.of]]\" variable=\"listItem\"><$reveal type=\"nomatch\" state=<<config-title>> text=\"hide\"><$transclude tiddler=<<listItem>>/></$reveal></$list></span>\n<div style=\"clear: both;\"></div>\n</div>\n"
},
"$:/core/ui/EditTemplate/fields": {
"title": "$:/core/ui/EditTemplate/fields",
"tags": "$:/tags/EditTemplate",
"text": "\\define lingo-base() $:/language/EditTemplate/\n\\define config-title()\n$:/config/EditTemplateFields/Visibility/$(currentField)$\n\\end\n\n\\define config-filter()\n[[hide]] -[title{$(config-title)$}]\n\\end\n\n\\define new-field()\n<$vars name={{$:/temp/newfieldname}}>\n<$reveal type=\"nomatch\" text=\"\" default=<<name>>>\n<$button>\n<$action-sendmessage $message=\"tm-add-field\"\n$name=<<name>>\n$value={{$:/temp/newfieldvalue}}/>\n<$action-deletetiddler $tiddler=\"$:/temp/newfieldname\"/>\n<$action-deletetiddler $tiddler=\"$:/temp/newfieldvalue\"/>\n<<lingo Fields/Add/Button>>\n</$button>\n</$reveal>\n<$reveal type=\"match\" text=\"\" default=<<name>>>\n<$button>\n<<lingo Fields/Add/Button>>\n</$button>\n</$reveal>\n</$vars>\n\\end\n\n<div class=\"tc-edit-fields\">\n<table class=\"tc-edit-fields\">\n<tbody>\n<$list filter=\"[all[current]fields[]] +[sort[title]]\" variable=\"currentField\">\n<$list filter=<<config-filter>> variable=\"temp\">\n<tr class=\"tc-edit-field\">\n<td class=\"tc-edit-field-name\">\n<$text text=<<currentField>>/>:</td>\n<td class=\"tc-edit-field-value\">\n<$edit-text tiddler=<<currentTiddler>> field=<<currentField>> placeholder={{$:/language/EditTemplate/Fields/Add/Value/Placeholder}}/>\n</td>\n<td class=\"tc-edit-field-remove\">\n<$button class=\"tc-btn-invisible\" tooltip={{$:/language/EditTemplate/Field/Remove/Hint}} aria-label={{$:/language/EditTemplate/Field/Remove/Caption}}>\n<$action-deletefield $field=<<currentField>>/>\n{{$:/core/images/delete-button}}\n</$button>\n</td>\n</tr>\n</$list>\n</$list>\n</tbody>\n</table>\n</div>\n\n<$fieldmangler>\n<div class=\"tc-edit-field-add\">\n<em class=\"tc-edit\">\n<<lingo Fields/Add/Prompt>>\n</em>\n<span class=\"tc-edit-field-add-name\">\n<$edit-text tiddler=\"$:/temp/newfieldname\" tag=\"input\" default=\"\" placeholder={{$:/language/EditTemplate/Fields/Add/Name/Placeholder}} focusPopup=<<qualify \"$:/state/popup/field-dropdown\">> class=\"tc-edit-texteditor tc-popup-handle\"/>\n</span>\n<$button popup=<<qualify \"$:/state/popup/field-dropdown\">> class=\"tc-btn-invisible tc-btn-dropdown\" tooltip={{$:/language/EditTemplate/Field/Dropdown/Hint}} aria-label={{$:/language/EditTemplate/Field/Dropdown/Caption}}>{{$:/core/images/down-arrow}}</$button>\n<$reveal state=<<qualify \"$:/state/popup/field-dropdown\">> type=\"nomatch\" text=\"\" default=\"\">\n<div class=\"tc-block-dropdown tc-edit-type-dropdown\">\n<$set name=\"tv-show-missing-links\" value=\"yes\">\n<$linkcatcher to=\"$:/temp/newfieldname\">\n<div class=\"tc-dropdown-item\">\n<<lingo Fields/Add/Dropdown/User>>\n</div>\n<$list filter=\"[!is[shadow]!is[system]fields[]search:title{$:/temp/newfieldname}sort[]] -created -creator -draft.of -draft.title -modified -modifier -tags -text -title -type\" variable=\"currentField\">\n<$link to=<<currentField>>>\n<<currentField>>\n</$link>\n</$list>\n<div class=\"tc-dropdown-item\">\n<<lingo Fields/Add/Dropdown/System>>\n</div>\n<$list filter=\"[fields[]search:title{$:/temp/newfieldname}sort[]] -[!is[shadow]!is[system]fields[]]\" variable=\"currentField\">\n<$link to=<<currentField>>>\n<<currentField>>\n</$link>\n</$list>\n</$linkcatcher>\n</$set>\n</div>\n</$reveal>\n<span class=\"tc-edit-field-add-value\">\n<$edit-text tiddler=\"$:/temp/newfieldvalue\" tag=\"input\" default=\"\" placeholder={{$:/language/EditTemplate/Fields/Add/Value/Placeholder}} class=\"tc-edit-texteditor\"/>\n</span>\n<span class=\"tc-edit-field-add-button\">\n<$macrocall $name=\"new-field\"/>\n</span>\n</div>\n</$fieldmangler>\n"
},
"$:/core/ui/EditTemplate/shadow": {
"title": "$:/core/ui/EditTemplate/shadow",
"tags": "$:/tags/EditTemplate",
"text": "\\define lingo-base() $:/language/EditTemplate/Shadow/\n\\define pluginLinkBody()\n<$link to=\"\"\"$(pluginTitle)$\"\"\">\n<$text text=\"\"\"$(pluginTitle)$\"\"\"/>\n</$link>\n\\end\n<$list filter=\"[all[current]get[draft.of]is[shadow]!is[tiddler]]\">\n\n<$list filter=\"[all[current]shadowsource[]]\" variable=\"pluginTitle\">\n\n<$set name=\"pluginLink\" value=<<pluginLinkBody>>>\n<div class=\"tc-message-box\">\n\n<<lingo Warning>>\n\n</div>\n</$set>\n</$list>\n\n</$list>\n\n<$list filter=\"[all[current]get[draft.of]is[shadow]is[tiddler]]\">\n\n<$list filter=\"[all[current]shadowsource[]]\" variable=\"pluginTitle\">\n\n<$set name=\"pluginLink\" value=<<pluginLinkBody>>>\n<div class=\"tc-message-box\">\n\n<<lingo OverriddenWarning>>\n\n</div>\n</$set>\n</$list>\n\n</$list>"
},
"$:/core/ui/EditTemplate/tags": {
"title": "$:/core/ui/EditTemplate/tags",
"tags": "$:/tags/EditTemplate",
"text": "\\whitespace trim\n\n\\define lingo-base() $:/language/EditTemplate/\n\n\\define tag-styles()\nbackground-color:$(backgroundColor)$;\nfill:$(foregroundColor)$;\ncolor:$(foregroundColor)$;\n\\end\n\n\\define tag-body-inner(colour,fallbackTarget,colourA,colourB,icon)\n\\whitespace trim\n<$vars foregroundColor=<<contrastcolour target:\"\"\"$colour$\"\"\" fallbackTarget:\"\"\"$fallbackTarget$\"\"\" colourA:\"\"\"$colourA$\"\"\" colourB:\"\"\"$colourB$\"\"\">> backgroundColor=\"\"\"$colour$\"\"\">\n<span style=<<tag-styles>> class=\"tc-tag-label tc-tag-list-item\">\n<$transclude tiddler=\"\"\"$icon$\"\"\"/> <$view field=\"title\" format=\"text\" />\n<$button message=\"tm-remove-tag\" param={{!!title}} class=\"tc-btn-invisible tc-remove-tag-button\">×</$button>\n</span>\n</$vars>\n\\end\n\n\\define tag-body(colour,palette,icon)\n<$macrocall $name=\"tag-body-inner\" colour=\"\"\"$colour$\"\"\" fallbackTarget={{$palette$##tag-background}} colourA={{$palette$##foreground}} colourB={{$palette$##background}} icon=\"\"\"$icon$\"\"\"/>\n\\end\n\n\\define tag-picker-actions()\n<$action-listops\n\t$tiddler=<<currentTiddler>>\n\t$field=\"tags\"\n\t$subfilter=\"[<tag>] [all[current]tags[]]\"\n/>\n\\end\n\n<div class=\"tc-edit-tags\">\n<$fieldmangler>\n<$list filter=\"[all[current]tags[]sort[title]]\" storyview=\"pop\">\n<$macrocall $name=\"tag-body\" colour={{!!color}} palette={{$:/palette}} icon={{!!icon}}/>\n</$list>\n</$fieldmangler>\n<$macrocall $name=\"tag-picker\" actions=<<tag-picker-actions>>/>\n</div>\n"
},
"$:/core/ui/EditTemplate/title": {
"title": "$:/core/ui/EditTemplate/title",
"tags": "$:/tags/EditTemplate",
"text": "<$edit-text field=\"draft.title\" class=\"tc-titlebar tc-edit-texteditor\" focus=\"true\"/>\n\n<$vars pattern=\"\"\"[\\|\\[\\]{}]\"\"\" bad-chars=\"\"\"`| [ ] { }`\"\"\">\n\n<$list filter=\"[all[current]regexp:draft.title<pattern>]\" variable=\"listItem\">\n\n<div class=\"tc-message-box\">\n\n{{$:/core/images/warning}} {{$:/language/EditTemplate/Title/BadCharacterWarning}}\n\n</div>\n\n</$list>\n\n</$vars>\n\n<$reveal state=\"!!draft.title\" type=\"nomatch\" text={{!!draft.of}} tag=\"div\">\n\n<$list filter=\"[{!!draft.title}!is[missing]]\" variable=\"listItem\">\n\n<div class=\"tc-message-box\">\n\n{{$:/core/images/warning}} {{$:/language/EditTemplate/Title/Exists/Prompt}}\n\n</div>\n\n</$list>\n\n<$list filter=\"[{!!draft.of}!is[missing]]\" variable=\"listItem\">\n\n<$vars fromTitle={{!!draft.of}} toTitle={{!!draft.title}}>\n\n<$checkbox tiddler=\"$:/config/RelinkOnRename\" field=\"text\" checked=\"yes\" unchecked=\"no\" default=\"no\"> {{$:/language/EditTemplate/Title/Relink/Prompt}}</$checkbox>\n\n<$vars stateTiddler=<<qualify \"$:/state/edit/references\">> >\n\n<$reveal type=\"nomatch\" state=<<stateTiddler>> text=\"show\">\n<$button set=<<stateTiddler>> setTo=\"show\" class=\"tc-btn-invisible\">{{$:/core/images/right-arrow}} \n<<lingo EditTemplate/Title/References/Prompt>></$button>\n</$reveal>\n<$reveal type=\"match\" state=<<stateTiddler>> text=\"show\">\n<$button set=<<stateTiddler>> setTo=\"hide\" class=\"tc-btn-invisible\">{{$:/core/images/down-arrow}} \n<<lingo EditTemplate/Title/References/Prompt>></$button>\n</$reveal>\n\n<$reveal type=\"match\" state=<<stateTiddler>> text=\"show\">\n<$tiddler tiddler=<<fromTitle>> >\n<$transclude tiddler=\"$:/core/ui/TiddlerInfo/References\"/>\n</$tiddler>\n</$reveal>\n\n</$vars>\n\n</$vars>\n\n</$list>\n\n</$reveal>\n"
},
"$:/core/ui/EditTemplate/type": {
"title": "$:/core/ui/EditTemplate/type",
"tags": "$:/tags/EditTemplate",
"text": "\\define lingo-base() $:/language/EditTemplate/\n<div class=\"tc-type-selector\"><$fieldmangler>\n<em class=\"tc-edit\"><<lingo Type/Prompt>></em> <$edit-text field=\"type\" tag=\"input\" default=\"\" placeholder={{$:/language/EditTemplate/Type/Placeholder}} focusPopup=<<qualify \"$:/state/popup/type-dropdown\">> class=\"tc-edit-typeeditor tc-popup-handle\"/> <$button popup=<<qualify \"$:/state/popup/type-dropdown\">> class=\"tc-btn-invisible tc-btn-dropdown\" tooltip={{$:/language/EditTemplate/Type/Dropdown/Hint}} aria-label={{$:/language/EditTemplate/Type/Dropdown/Caption}}>{{$:/core/images/down-arrow}}</$button> <$button message=\"tm-remove-field\" param=\"type\" class=\"tc-btn-invisible tc-btn-icon\" tooltip={{$:/language/EditTemplate/Type/Delete/Hint}} aria-label={{$:/language/EditTemplate/Type/Delete/Caption}}>{{$:/core/images/delete-button}}</$button>\n</$fieldmangler></div>\n\n<div class=\"tc-block-dropdown-wrapper\">\n<$set name=\"tv-show-missing-links\" value=\"yes\">\n<$reveal state=<<qualify \"$:/state/popup/type-dropdown\">> type=\"nomatch\" text=\"\" default=\"\">\n<div class=\"tc-block-dropdown tc-edit-type-dropdown\">\n<$linkcatcher to=\"!!type\">\n<$list filter='[all[shadows+tiddlers]prefix[$:/language/Docs/Types/]each[group]sort[group-sort]]'>\n<div class=\"tc-dropdown-item\">\n<$text text={{!!group}}/>\n</div>\n<$list filter=\"[all[shadows+tiddlers]prefix[$:/language/Docs/Types/]group{!!group}] +[sort[description]]\"><$link to={{!!name}}><$view field=\"description\"/> (<$view field=\"name\"/>)</$link>\n</$list>\n</$list>\n</$linkcatcher>\n</div>\n</$reveal>\n</$set>\n</div>\n"
},
"$:/core/ui/EditTemplate": {
"title": "$:/core/ui/EditTemplate",
"text": "\\define actions()\n<$action-sendmessage $message=\"tm-add-tag\" $param={{$:/temp/NewTagName}}/>\n<$action-deletetiddler $tiddler=\"$:/temp/NewTagName\"/>\n<$action-sendmessage $message=\"tm-add-field\" $name={{$:/temp/newfieldname}} $value={{$:/temp/newfieldvalue}}/>\n<$action-deletetiddler $tiddler=\"$:/temp/newfieldname\"/>\n<$action-deletetiddler $tiddler=\"$:/temp/newfieldvalue\"/>\n<$action-sendmessage $message=\"tm-save-tiddler\"/>\n\\end\n\\define frame-classes()\ntc-tiddler-frame tc-tiddler-edit-frame $(missingTiddlerClass)$ $(shadowTiddlerClass)$ $(systemTiddlerClass)$\n\\end\n<div class=<<frame-classes>> data-tiddler-title=<<currentTiddler>>>\n<$fieldmangler>\n<$set name=\"storyTiddler\" value=<<currentTiddler>>>\n<$keyboard key=\"((cancel-edit-tiddler))\" message=\"tm-cancel-tiddler\">\n<$keyboard key=\"((save-tiddler))\" actions=<<actions>>>\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/EditTemplate]!has[draft.of]]\" variable=\"listItem\">\n<$set name=\"tv-config-toolbar-class\" filter=\"[<tv-config-toolbar-class>] [<listItem>encodeuricomponent[]addprefix[tc-btn-]]\">\n<$transclude tiddler=<<listItem>>/>\n</$set>\n</$list>\n</$keyboard>\n</$keyboard>\n</$set>\n</$fieldmangler>\n</div>\n"
},
"$:/core/ui/Buttons/cancel": {
"title": "$:/core/ui/Buttons/cancel",
"tags": "$:/tags/EditToolbar",
"caption": "{{$:/core/images/cancel-button}} {{$:/language/Buttons/Cancel/Caption}}",
"description": "{{$:/language/Buttons/Cancel/Hint}}",
"text": "<$button message=\"tm-cancel-tiddler\" tooltip={{$:/language/Buttons/Cancel/Hint}} aria-label={{$:/language/Buttons/Cancel/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/cancel-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Cancel/Caption}}/></span>\n</$list>\n</$button>"
},
"$:/core/ui/Buttons/delete": {
"title": "$:/core/ui/Buttons/delete",
"tags": "$:/tags/EditToolbar $:/tags/ViewToolbar",
"caption": "{{$:/core/images/delete-button}} {{$:/language/Buttons/Delete/Caption}}",
"description": "{{$:/language/Buttons/Delete/Hint}}",
"text": "<$button message=\"tm-delete-tiddler\" tooltip={{$:/language/Buttons/Delete/Hint}} aria-label={{$:/language/Buttons/Delete/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/delete-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Delete/Caption}}/></span>\n</$list>\n</$button>"
},
"$:/core/ui/Buttons/save": {
"title": "$:/core/ui/Buttons/save",
"tags": "$:/tags/EditToolbar",
"caption": "{{$:/core/images/done-button}} {{$:/language/Buttons/Save/Caption}}",
"description": "{{$:/language/Buttons/Save/Hint}}",
"text": "<$fieldmangler><$button tooltip={{$:/language/Buttons/Save/Hint}} aria-label={{$:/language/Buttons/Save/Caption}} class=<<tv-config-toolbar-class>>>\n<$action-sendmessage $message=\"tm-add-tag\" $param={{$:/temp/NewTagName}}/>\n<$action-deletetiddler $tiddler=\"$:/temp/NewTagName\"/>\n<$action-sendmessage $message=\"tm-add-field\" $name={{$:/temp/newfieldname}} $value={{$:/temp/newfieldvalue}}/>\n<$action-deletetiddler $tiddler=\"$:/temp/newfieldname\"/>\n<$action-deletetiddler $tiddler=\"$:/temp/newfieldvalue\"/>\n<$action-sendmessage $message=\"tm-save-tiddler\"/>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/done-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Save/Caption}}/></span>\n</$list>\n</$button></$fieldmangler>\n"
},
"$:/core/ui/EditorToolbar/bold": {
"title": "$:/core/ui/EditorToolbar/bold",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/bold",
"caption": "{{$:/language/Buttons/Bold/Caption}}",
"description": "{{$:/language/Buttons/Bold/Hint}}",
"condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
"shortcuts": "((bold))",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"wrap-selection\"\n\tprefix=\"''\"\n\tsuffix=\"''\"\n/>\n"
},
"$:/core/ui/EditorToolbar/clear-dropdown": {
"title": "$:/core/ui/EditorToolbar/clear-dropdown",
"text": "''{{$:/language/Buttons/Clear/Hint}}''\n\n<div class=\"tc-colour-chooser\">\n\n<$macrocall $name=\"colour-picker\" actions=\"\"\"\n\n<$action-sendmessage\n\t$message=\"tm-edit-bitmap-operation\"\n\t$param=\"clear\"\n\tcolour=<<colour-picker-value>>\n/>\n\n<$action-deletetiddler\n\t$tiddler=<<dropdown-state>>\n/>\n\n\"\"\"/>\n\n</div>\n"
},
"$:/core/ui/EditorToolbar/clear": {
"title": "$:/core/ui/EditorToolbar/clear",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/erase",
"caption": "{{$:/language/Buttons/Clear/Caption}}",
"description": "{{$:/language/Buttons/Clear/Hint}}",
"condition": "[<targetTiddler>is[image]]",
"dropdown": "$:/core/ui/EditorToolbar/clear-dropdown",
"text": ""
},
"$:/core/ui/EditorToolbar/editor-height-dropdown": {
"title": "$:/core/ui/EditorToolbar/editor-height-dropdown",
"text": "\\define lingo-base() $:/language/Buttons/EditorHeight/\n''<<lingo Hint>>''\n\n<$radio tiddler=\"$:/config/TextEditor/EditorHeight/Mode\" value=\"auto\"> {{$:/core/images/auto-height}} <<lingo Caption/Auto>></$radio>\n\n<$radio tiddler=\"$:/config/TextEditor/EditorHeight/Mode\" value=\"fixed\"> {{$:/core/images/fixed-height}} <<lingo Caption/Fixed>> <$edit-text tag=\"input\" tiddler=\"$:/config/TextEditor/EditorHeight/Height\" default=\"100px\"/></$radio>\n"
},
"$:/core/ui/EditorToolbar/editor-height": {
"title": "$:/core/ui/EditorToolbar/editor-height",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/fixed-height",
"custom-icon": "yes",
"caption": "{{$:/language/Buttons/EditorHeight/Caption}}",
"description": "{{$:/language/Buttons/EditorHeight/Hint}}",
"condition": "[<targetTiddler>type[]] [<targetTiddler>get[type]prefix[text/]] +[first[]]",
"dropdown": "$:/core/ui/EditorToolbar/editor-height-dropdown",
"text": "<$reveal tag=\"span\" state=\"$:/config/TextEditor/EditorHeight/Mode\" type=\"match\" text=\"fixed\">\n{{$:/core/images/fixed-height}}\n</$reveal>\n<$reveal tag=\"span\" state=\"$:/config/TextEditor/EditorHeight/Mode\" type=\"match\" text=\"auto\">\n{{$:/core/images/auto-height}}\n</$reveal>\n"
},
"$:/core/ui/EditorToolbar/excise-dropdown": {
"title": "$:/core/ui/EditorToolbar/excise-dropdown",
"text": "\\define lingo-base() $:/language/Buttons/Excise/\n\n\\define body(config-title)\n''<<lingo Hint>>''\n\n<<lingo Caption/NewTitle>> <$edit-text tag=\"input\" tiddler=\"$config-title$/new-title\" default=\"\" focus=\"true\"/>\n\n<$set name=\"new-title\" value={{$config-title$/new-title}}>\n<$list filter=\"\"\"[<new-title>is[tiddler]]\"\"\">\n<div class=\"tc-error\">\n<<lingo Caption/TiddlerExists>>\n</div>\n</$list>\n</$set>\n\n<$checkbox tiddler=\"\"\"$config-title$/tagnew\"\"\" field=\"text\" checked=\"yes\" unchecked=\"no\" default=\"false\"> <<lingo Caption/Tag>></$checkbox>\n\n<<lingo Caption/Replace>> <$select tiddler=\"\"\"$config-title$/type\"\"\" default=\"transclude\">\n<option value=\"link\"><<lingo Caption/Replace/Link>></option>\n<option value=\"transclude\"><<lingo Caption/Replace/Transclusion>></option>\n<option value=\"macro\"><<lingo Caption/Replace/Macro>></option>\n</$select>\n\n<$reveal state=\"\"\"$config-title$/type\"\"\" type=\"match\" text=\"macro\">\n<<lingo Caption/MacroName>> <$edit-text tag=\"input\" tiddler=\"\"\"$config-title$/macro-title\"\"\" default=\"translink\"/>\n</$reveal>\n\n<$button>\n<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"excise\"\n\ttitle={{$config-title$/new-title}}\n\ttype={{$config-title$/type}}\n\tmacro={{$config-title$/macro-title}}\n\ttagnew={{$config-title$/tagnew}}\n/>\n<$action-deletetiddler\n\t$tiddler=\"$config-title$/new-title\"\n/>\n<$action-deletetiddler\n\t$tiddler=<<dropdown-state>>\n/>\n<<lingo Caption/Excise>>\n</$button>\n\\end\n\n<$macrocall $name=\"body\" config-title=<<qualify \"$:/state/Excise/\">>/>\n"
},
"$:/core/ui/EditorToolbar/excise": {
"title": "$:/core/ui/EditorToolbar/excise",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/excise",
"caption": "{{$:/language/Buttons/Excise/Caption}}",
"description": "{{$:/language/Buttons/Excise/Hint}}",
"condition": "[<targetTiddler>type[]] [<targetTiddler>type[text/vnd.tiddlywiki]] +[first[]]",
"shortcuts": "((excise))",
"dropdown": "$:/core/ui/EditorToolbar/excise-dropdown",
"text": ""
},
"$:/core/ui/EditorToolbar/heading-1": {
"title": "$:/core/ui/EditorToolbar/heading-1",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/heading-1",
"caption": "{{$:/language/Buttons/Heading1/Caption}}",
"description": "{{$:/language/Buttons/Heading1/Hint}}",
"condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
"button-classes": "tc-text-editor-toolbar-item-start-group",
"shortcuts": "((heading-1))",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"prefix-lines\"\n\tcharacter=\"!\"\n\tcount=\"1\"\n/>\n"
},
"$:/core/ui/EditorToolbar/heading-2": {
"title": "$:/core/ui/EditorToolbar/heading-2",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/heading-2",
"caption": "{{$:/language/Buttons/Heading2/Caption}}",
"description": "{{$:/language/Buttons/Heading2/Hint}}",
"condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
"shortcuts": "((heading-2))",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"prefix-lines\"\n\tcharacter=\"!\"\n\tcount=\"2\"\n/>\n"
},
"$:/core/ui/EditorToolbar/heading-3": {
"title": "$:/core/ui/EditorToolbar/heading-3",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/heading-3",
"caption": "{{$:/language/Buttons/Heading3/Caption}}",
"description": "{{$:/language/Buttons/Heading3/Hint}}",
"condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
"shortcuts": "((heading-3))",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"prefix-lines\"\n\tcharacter=\"!\"\n\tcount=\"3\"\n/>\n"
},
"$:/core/ui/EditorToolbar/heading-4": {
"title": "$:/core/ui/EditorToolbar/heading-4",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/heading-4",
"caption": "{{$:/language/Buttons/Heading4/Caption}}",
"description": "{{$:/language/Buttons/Heading4/Hint}}",
"condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
"shortcuts": "((heading-4))",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"prefix-lines\"\n\tcharacter=\"!\"\n\tcount=\"4\"\n/>\n"
},
"$:/core/ui/EditorToolbar/heading-5": {
"title": "$:/core/ui/EditorToolbar/heading-5",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/heading-5",
"caption": "{{$:/language/Buttons/Heading5/Caption}}",
"description": "{{$:/language/Buttons/Heading5/Hint}}",
"condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
"shortcuts": "((heading-5))",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"prefix-lines\"\n\tcharacter=\"!\"\n\tcount=\"5\"\n/>\n"
},
"$:/core/ui/EditorToolbar/heading-6": {
"title": "$:/core/ui/EditorToolbar/heading-6",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/heading-6",
"caption": "{{$:/language/Buttons/Heading6/Caption}}",
"description": "{{$:/language/Buttons/Heading6/Hint}}",
"condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
"shortcuts": "((heading-6))",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"prefix-lines\"\n\tcharacter=\"!\"\n\tcount=\"6\"\n/>\n"
},
"$:/core/ui/EditorToolbar/italic": {
"title": "$:/core/ui/EditorToolbar/italic",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/italic",
"caption": "{{$:/language/Buttons/Italic/Caption}}",
"description": "{{$:/language/Buttons/Italic/Hint}}",
"condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
"shortcuts": "((italic))",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"wrap-selection\"\n\tprefix=\"//\"\n\tsuffix=\"//\"\n/>\n"
},
"$:/core/ui/EditorToolbar/line-width-dropdown": {
"title": "$:/core/ui/EditorToolbar/line-width-dropdown",
"text": "\\define lingo-base() $:/language/Buttons/LineWidth/\n\n\\define toolbar-line-width-inner()\n<$button tag=\"a\" tooltip=\"\"\"$(line-width)$\"\"\">\n\n<$action-setfield\n\t$tiddler=\"$:/config/BitmapEditor/LineWidth\"\n\t$value=\"$(line-width)$\"\n/>\n\n<$action-deletetiddler\n\t$tiddler=<<dropdown-state>>\n/>\n\n<div style=\"display: inline-block; margin: 4px calc(80px - $(line-width)$); background-color: #000; width: calc(100px + $(line-width)$ * 2); height: $(line-width)$; border-radius: 120px; vertical-align: middle;\"/>\n\n<span style=\"margin-left: 8px;\">\n\n<$text text=\"\"\"$(line-width)$\"\"\"/>\n\n<$reveal state=\"$:/config/BitmapEditor/LineWidth\" type=\"match\" text=\"\"\"$(line-width)$\"\"\" tag=\"span\">\n\n<$entity entity=\" \"/>\n\n<$entity entity=\"✓\"/>\n\n</$reveal>\n\n</span>\n\n</$button>\n\\end\n\n''<<lingo Hint>>''\n\n<$list filter={{$:/config/BitmapEditor/LineWidths}} variable=\"line-width\">\n\n<<toolbar-line-width-inner>>\n\n</$list>\n"
},
"$:/core/ui/EditorToolbar/line-width": {
"title": "$:/core/ui/EditorToolbar/line-width",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/line-width",
"caption": "{{$:/language/Buttons/LineWidth/Caption}}",
"description": "{{$:/language/Buttons/LineWidth/Hint}}",
"condition": "[<targetTiddler>is[image]]",
"dropdown": "$:/core/ui/EditorToolbar/line-width-dropdown",
"text": "<$text text={{$:/config/BitmapEditor/LineWidth}}/>"
},
"$:/core/ui/EditorToolbar/link-dropdown": {
"title": "$:/core/ui/EditorToolbar/link-dropdown",
"text": "\\define lingo-base() $:/language/Buttons/Link/\n\n\\define add-link-actions()\n<$action-sendmessage $message=\"tm-edit-text-operation\" $param=\"make-link\" text={{$(linkTiddler)$}} />\n<$action-deletetiddler $tiddler=<<dropdown-state>> />\n<$action-deletetiddler $tiddler=<<searchTiddler>> />\n<$action-deletetiddler $tiddler=<<linkTiddler>> />\n\\end\n\n\\define external-link()\n<$button class=\"tc-btn-invisible\" style=\"width: auto; display: inline-block; background-colour: inherit;\" actions=<<add-link-actions>>>\n{{$:/core/images/chevron-right}}\n</$button>\n\\end\n\n\\define body(config-title)\n''<<lingo Hint>>''\n\n<$vars searchTiddler=\"\"\"$config-title$/search\"\"\" linkTiddler=\"\"\"$config-title$/link\"\"\" linktext=\"\" >\n\n<$vars linkTiddler=<<searchTiddler>>>\n<$keyboard key=\"ENTER\" actions=<<add-link-actions>>>\n<$edit-text tiddler=<<searchTiddler>> type=\"search\" tag=\"input\" focus=\"true\" placeholder={{$:/language/Search/Search}} default=\"\"/>\n<$reveal tag=\"span\" state=<<searchTiddler>> type=\"nomatch\" text=\"\">\n<<external-link>>\n<$button class=\"tc-btn-invisible\" style=\"width: auto; display: inline-block; background-colour: inherit;\">\n<$action-setfield $tiddler=<<searchTiddler>> text=\"\" />\n{{$:/core/images/close-button}}\n</$button>\n</$reveal>\n</$keyboard>\n</$vars>\n\n<$reveal tag=\"div\" state=<<searchTiddler>> type=\"nomatch\" text=\"\">\n\n<$linkcatcher actions=<<add-link-actions>> to=<<linkTiddler>>>\n\n{{$:/core/ui/SearchResults}}\n\n</$linkcatcher>\n\n</$reveal>\n\n</$vars>\n\n\\end\n\n<$macrocall $name=\"body\" config-title=<<qualify \"$:/state/Link/\">>/>"
},
"$:/core/ui/EditorToolbar/link": {
"title": "$:/core/ui/EditorToolbar/link",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/link",
"caption": "{{$:/language/Buttons/Link/Caption}}",
"description": "{{$:/language/Buttons/Link/Hint}}",
"condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
"button-classes": "tc-text-editor-toolbar-item-start-group",
"shortcuts": "((link))",
"dropdown": "$:/core/ui/EditorToolbar/link-dropdown",
"text": ""
},
"$:/core/ui/EditorToolbar/linkify": {
"title": "$:/core/ui/EditorToolbar/linkify",
"caption": "{{$:/language/Buttons/Linkify/Caption}}",
"condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
"description": "{{$:/language/Buttons/Linkify/Hint}}",
"icon": "$:/core/images/linkify",
"list-before": "$:/core/ui/EditorToolbar/mono-block",
"shortcuts": "((linkify))",
"tags": "$:/tags/EditorToolbar",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"wrap-selection\"\n\tprefix=\"[[\"\n\tsuffix=\"]]\"\n/>\n"
},
"$:/core/ui/EditorToolbar/list-bullet": {
"title": "$:/core/ui/EditorToolbar/list-bullet",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/list-bullet",
"caption": "{{$:/language/Buttons/ListBullet/Caption}}",
"description": "{{$:/language/Buttons/ListBullet/Hint}}",
"condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
"shortcuts": "((list-bullet))",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"prefix-lines\"\n\tcharacter=\"*\"\n\tcount=\"1\"\n/>\n"
},
"$:/core/ui/EditorToolbar/list-number": {
"title": "$:/core/ui/EditorToolbar/list-number",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/list-number",
"caption": "{{$:/language/Buttons/ListNumber/Caption}}",
"description": "{{$:/language/Buttons/ListNumber/Hint}}",
"condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
"shortcuts": "((list-number))",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"prefix-lines\"\n\tcharacter=\"#\"\n\tcount=\"1\"\n/>\n"
},
"$:/core/ui/EditorToolbar/mono-block": {
"title": "$:/core/ui/EditorToolbar/mono-block",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/mono-block",
"caption": "{{$:/language/Buttons/MonoBlock/Caption}}",
"description": "{{$:/language/Buttons/MonoBlock/Hint}}",
"condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
"button-classes": "tc-text-editor-toolbar-item-start-group",
"shortcuts": "((mono-block))",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"wrap-lines\"\n\tprefix=\"\n```\"\n\tsuffix=\"```\"\n/>\n"
},
"$:/core/ui/EditorToolbar/mono-line": {
"title": "$:/core/ui/EditorToolbar/mono-line",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/mono-line",
"caption": "{{$:/language/Buttons/MonoLine/Caption}}",
"description": "{{$:/language/Buttons/MonoLine/Hint}}",
"condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
"shortcuts": "((mono-line))",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"wrap-selection\"\n\tprefix=\"`\"\n\tsuffix=\"`\"\n/>\n"
},
"$:/core/ui/EditorToolbar/more-dropdown": {
"title": "$:/core/ui/EditorToolbar/more-dropdown",
"text": "\\define config-title()\n$:/config/EditorToolbarButtons/Visibility/$(toolbarItem)$\n\\end\n\n\\define conditional-button()\n<$list filter={{$(toolbarItem)$!!condition}} variable=\"condition\">\n<$transclude tiddler=\"$:/core/ui/EditTemplate/body/toolbar/button\" mode=\"inline\"/> <$transclude tiddler=<<toolbarItem>> field=\"description\"/>\n</$list>\n\\end\n\n<div class=\"tc-text-editor-toolbar-more\">\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/EditorToolbar]!has[draft.of]] -[[$:/core/ui/EditorToolbar/more]]\">\n<$reveal type=\"match\" state=<<config-visibility-title>> text=\"hide\" tag=\"div\">\n<<conditional-button>>\n</$reveal>\n</$list>\n</div>\n"
},
"$:/core/ui/EditorToolbar/more": {
"title": "$:/core/ui/EditorToolbar/more",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/down-arrow",
"caption": "{{$:/language/Buttons/More/Caption}}",
"description": "{{$:/language/Buttons/More/Hint}}",
"condition": "[<targetTiddler>]",
"dropdown": "$:/core/ui/EditorToolbar/more-dropdown",
"text": ""
},
"$:/core/ui/EditorToolbar/opacity-dropdown": {
"title": "$:/core/ui/EditorToolbar/opacity-dropdown",
"text": "\\define lingo-base() $:/language/Buttons/Opacity/\n\n\\define toolbar-opacity-inner()\n<$button tag=\"a\" tooltip=\"\"\"$(opacity)$\"\"\">\n\n<$action-setfield\n\t$tiddler=\"$:/config/BitmapEditor/Opacity\"\n\t$value=\"$(opacity)$\"\n/>\n\n<$action-deletetiddler\n\t$tiddler=<<dropdown-state>>\n/>\n\n<div style=\"display: inline-block; vertical-align: middle; background-color: $(current-paint-colour)$; opacity: $(opacity)$; width: 1em; height: 1em; border-radius: 50%;\"/>\n\n<span style=\"margin-left: 8px;\">\n\n<$text text=\"\"\"$(opacity)$\"\"\"/>\n\n<$reveal state=\"$:/config/BitmapEditor/Opacity\" type=\"match\" text=\"\"\"$(opacity)$\"\"\" tag=\"span\">\n\n<$entity entity=\" \"/>\n\n<$entity entity=\"✓\"/>\n\n</$reveal>\n\n</span>\n\n</$button>\n\\end\n\n\\define toolbar-opacity()\n''<<lingo Hint>>''\n\n<$list filter={{$:/config/BitmapEditor/Opacities}} variable=\"opacity\">\n\n<<toolbar-opacity-inner>>\n\n</$list>\n\\end\n\n<$set name=\"current-paint-colour\" value={{$:/config/BitmapEditor/Colour}}>\n\n<$set name=\"current-opacity\" value={{$:/config/BitmapEditor/Opacity}}>\n\n<<toolbar-opacity>>\n\n</$set>\n\n</$set>\n"
},
"$:/core/ui/EditorToolbar/opacity": {
"title": "$:/core/ui/EditorToolbar/opacity",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/opacity",
"caption": "{{$:/language/Buttons/Opacity/Caption}}",
"description": "{{$:/language/Buttons/Opacity/Hint}}",
"condition": "[<targetTiddler>is[image]]",
"dropdown": "$:/core/ui/EditorToolbar/opacity-dropdown",
"text": "<$text text={{$:/config/BitmapEditor/Opacity}}/>\n"
},
"$:/core/ui/EditorToolbar/paint-dropdown": {
"title": "$:/core/ui/EditorToolbar/paint-dropdown",
"text": "''{{$:/language/Buttons/Paint/Hint}}''\n\n<$macrocall $name=\"colour-picker\" actions=\"\"\"\n\n<$action-setfield\n\t$tiddler=\"$:/config/BitmapEditor/Colour\"\n\t$value=<<colour-picker-value>>\n/>\n\n<$action-deletetiddler\n\t$tiddler=<<dropdown-state>>\n/>\n\n\"\"\"/>\n"
},
"$:/core/ui/EditorToolbar/paint": {
"title": "$:/core/ui/EditorToolbar/paint",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/paint",
"caption": "{{$:/language/Buttons/Paint/Caption}}",
"description": "{{$:/language/Buttons/Paint/Hint}}",
"condition": "[<targetTiddler>is[image]]",
"dropdown": "$:/core/ui/EditorToolbar/paint-dropdown",
"text": "\\define toolbar-paint()\n<div style=\"display: inline-block; vertical-align: middle; background-color: $(colour-picker-value)$; width: 1em; height: 1em; border-radius: 50%;\"/>\n\\end\n<$set name=\"colour-picker-value\" value={{$:/config/BitmapEditor/Colour}}>\n<<toolbar-paint>>\n</$set>\n"
},
"$:/core/ui/EditorToolbar/picture-dropdown": {
"title": "$:/core/ui/EditorToolbar/picture-dropdown",
"text": "\\define replacement-text()\n[img[$(imageTitle)$]]\n\\end\n\n''{{$:/language/Buttons/Picture/Hint}}''\n\n<$macrocall $name=\"image-picker\" actions=\"\"\"\n\n<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"replace-selection\"\n\ttext=<<replacement-text>>\n/>\n\n<$action-deletetiddler\n\t$tiddler=<<dropdown-state>>\n/>\n\n\"\"\"/>\n"
},
"$:/core/ui/EditorToolbar/picture": {
"title": "$:/core/ui/EditorToolbar/picture",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/picture",
"caption": "{{$:/language/Buttons/Picture/Caption}}",
"description": "{{$:/language/Buttons/Picture/Hint}}",
"condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
"shortcuts": "((picture))",
"dropdown": "$:/core/ui/EditorToolbar/picture-dropdown",
"text": ""
},
"$:/core/ui/EditorToolbar/preview-type-dropdown": {
"title": "$:/core/ui/EditorToolbar/preview-type-dropdown",
"text": "\\define preview-type-button()\n<$button tag=\"a\">\n\n<$action-setfield $tiddler=\"$:/state/editpreviewtype\" $value=\"$(previewType)$\"/>\n\n<$action-deletetiddler\n\t$tiddler=<<dropdown-state>>\n/>\n\n<$transclude tiddler=<<previewType>> field=\"caption\" mode=\"inline\">\n\n<$view tiddler=<<previewType>> field=\"title\" mode=\"inline\"/>\n\n</$transclude> \n\n<$reveal tag=\"span\" state=\"$:/state/editpreviewtype\" type=\"match\" text=<<previewType>> default=\"$:/core/ui/EditTemplate/body/preview/output\">\n\n<$entity entity=\" \"/>\n\n<$entity entity=\"✓\"/>\n\n</$reveal>\n\n</$button>\n\\end\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/EditPreview]!has[draft.of]]\" variable=\"previewType\">\n\n<<preview-type-button>>\n\n</$list>\n"
},
"$:/core/ui/EditorToolbar/preview-type": {
"title": "$:/core/ui/EditorToolbar/preview-type",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/chevron-down",
"caption": "{{$:/language/Buttons/PreviewType/Caption}}",
"description": "{{$:/language/Buttons/PreviewType/Hint}}",
"condition": "[all[shadows+tiddlers]tag[$:/tags/EditPreview]!has[draft.of]butfirst[]limit[1]]",
"button-classes": "tc-text-editor-toolbar-item-adjunct",
"dropdown": "$:/core/ui/EditorToolbar/preview-type-dropdown"
},
"$:/core/ui/EditorToolbar/preview": {
"title": "$:/core/ui/EditorToolbar/preview",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/preview-open",
"custom-icon": "yes",
"caption": "{{$:/language/Buttons/Preview/Caption}}",
"description": "{{$:/language/Buttons/Preview/Hint}}",
"condition": "[<targetTiddler>]",
"button-classes": "tc-text-editor-toolbar-item-start-group",
"shortcuts": "((preview))",
"text": "<$reveal state=\"$:/state/showeditpreview\" type=\"match\" text=\"yes\" tag=\"span\">\n{{$:/core/images/preview-open}}\n<$action-setfield $tiddler=\"$:/state/showeditpreview\" $value=\"no\"/>\n</$reveal>\n<$reveal state=\"$:/state/showeditpreview\" type=\"nomatch\" text=\"yes\" tag=\"span\">\n{{$:/core/images/preview-closed}}\n<$action-setfield $tiddler=\"$:/state/showeditpreview\" $value=\"yes\"/>\n</$reveal>\n"
},
"$:/core/ui/EditorToolbar/quote": {
"title": "$:/core/ui/EditorToolbar/quote",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/quote",
"caption": "{{$:/language/Buttons/Quote/Caption}}",
"description": "{{$:/language/Buttons/Quote/Hint}}",
"condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
"shortcuts": "((quote))",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"wrap-lines\"\n\tprefix=\"\n<<<\"\n\tsuffix=\"<<<\"\n/>\n"
},
"$:/core/ui/EditorToolbar/rotate-left": {
"title": "$:/core/ui/EditorToolbar/rotate-left",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/rotate-left",
"caption": "{{$:/language/Buttons/RotateLeft/Caption}}",
"description": "{{$:/language/Buttons/RotateLeft/Hint}}",
"condition": "[<targetTiddler>is[image]]",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-bitmap-operation\"\n\t$param=\"rotate-left\"\n/>\n"
},
"$:/core/ui/EditorToolbar/size-dropdown": {
"title": "$:/core/ui/EditorToolbar/size-dropdown",
"text": "\\define lingo-base() $:/language/Buttons/Size/\n\n\\define toolbar-button-size-preset(config-title)\n<$set name=\"width\" filter=\"$(sizePair)$ +[first[]]\">\n\n<$set name=\"height\" filter=\"$(sizePair)$ +[last[]]\">\n\n<$button tag=\"a\">\n\n<$action-setfield\n\t$tiddler=\"\"\"$config-title$/new-width\"\"\"\n\t$value=<<width>>\n/>\n\n<$action-setfield\n\t$tiddler=\"\"\"$config-title$/new-height\"\"\"\n\t$value=<<height>>\n/>\n\n<$action-deletetiddler\n\t$tiddler=\"\"\"$config-title$/presets-popup\"\"\"\n/>\n\n<$text text=<<width>>/> × <$text text=<<height>>/>\n\n</$button>\n\n</$set>\n\n</$set>\n\\end\n\n\\define toolbar-button-size(config-title)\n''{{$:/language/Buttons/Size/Hint}}''\n\n<<lingo Caption/Width>> <$edit-text tag=\"input\" tiddler=\"\"\"$config-title$/new-width\"\"\" default=<<tv-bitmap-editor-width>> focus=\"true\" size=\"8\"/> <<lingo Caption/Height>> <$edit-text tag=\"input\" tiddler=\"\"\"$config-title$/new-height\"\"\" default=<<tv-bitmap-editor-height>> size=\"8\"/> <$button popup=\"\"\"$config-title$/presets-popup\"\"\" class=\"tc-btn-invisible tc-popup-keep\" style=\"width: auto; display: inline-block; background-colour: inherit;\" selectedClass=\"tc-selected\">\n{{$:/core/images/down-arrow}}\n</$button>\n\n<$reveal tag=\"span\" state=\"\"\"$config-title$/presets-popup\"\"\" type=\"popup\" position=\"belowleft\" animate=\"yes\">\n\n<div class=\"tc-drop-down tc-popup-keep\">\n\n<$list filter={{$:/config/BitmapEditor/ImageSizes}} variable=\"sizePair\">\n\n<$macrocall $name=\"toolbar-button-size-preset\" config-title=\"$config-title$\"/>\n\n</$list>\n\n</div>\n\n</$reveal>\n\n<$button>\n<$action-sendmessage\n\t$message=\"tm-edit-bitmap-operation\"\n\t$param=\"resize\"\n\twidth={{$config-title$/new-width}}\n\theight={{$config-title$/new-height}}\n/>\n<$action-deletetiddler\n\t$tiddler=\"\"\"$config-title$/new-width\"\"\"\n/>\n<$action-deletetiddler\n\t$tiddler=\"\"\"$config-title$/new-height\"\"\"\n/>\n<$action-deletetiddler\n\t$tiddler=<<dropdown-state>>\n/>\n<<lingo Caption/Resize>>\n</$button>\n\\end\n\n<$macrocall $name=\"toolbar-button-size\" config-title=<<qualify \"$:/state/Size/\">>/>\n"
},
"$:/core/ui/EditorToolbar/size": {
"title": "$:/core/ui/EditorToolbar/size",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/size",
"caption": "{{$:/language/Buttons/Size/Caption}}",
"description": "{{$:/language/Buttons/Size/Hint}}",
"condition": "[<targetTiddler>is[image]]",
"dropdown": "$:/core/ui/EditorToolbar/size-dropdown",
"text": ""
},
"$:/core/ui/EditorToolbar/stamp-dropdown": {
"title": "$:/core/ui/EditorToolbar/stamp-dropdown",
"text": "\\define toolbar-button-stamp-inner()\n<$button tag=\"a\">\n\n<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"replace-selection\"\n\ttext={{$(snippetTitle)$}}\n/>\n\n<$action-deletetiddler\n\t$tiddler=<<dropdown-state>>\n/>\n\n<$view tiddler=<<snippetTitle>> field=\"caption\" mode=\"inline\">\n\n<$view tiddler=<<snippetTitle>> field=\"title\" mode=\"inline\"/>\n\n</$view>\n\n</$button>\n\\end\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/TextEditor/Snippet]!has[draft.of]sort[caption]]\" variable=\"snippetTitle\">\n\n<<toolbar-button-stamp-inner>>\n\n</$list>\n\n----\n\n<$button tag=\"a\">\n\n<$action-sendmessage\n\t$message=\"tm-new-tiddler\"\n\ttags=\"$:/tags/TextEditor/Snippet\"\n\tcaption={{$:/language/Buttons/Stamp/New/Title}}\n\ttext={{$:/language/Buttons/Stamp/New/Text}}\n/>\n\n<$action-deletetiddler\n\t$tiddler=<<dropdown-state>>\n/>\n\n<em>\n\n<$text text={{$:/language/Buttons/Stamp/Caption/New}}/>\n\n</em>\n\n</$button>\n"
},
"$:/core/ui/EditorToolbar/stamp": {
"title": "$:/core/ui/EditorToolbar/stamp",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/stamp",
"caption": "{{$:/language/Buttons/Stamp/Caption}}",
"description": "{{$:/language/Buttons/Stamp/Hint}}",
"condition": "[<targetTiddler>type[]] [<targetTiddler>get[type]prefix[text/]] +[first[]]",
"shortcuts": "((stamp))",
"dropdown": "$:/core/ui/EditorToolbar/stamp-dropdown",
"text": ""
},
"$:/core/ui/EditorToolbar/strikethrough": {
"title": "$:/core/ui/EditorToolbar/strikethrough",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/strikethrough",
"caption": "{{$:/language/Buttons/Strikethrough/Caption}}",
"description": "{{$:/language/Buttons/Strikethrough/Hint}}",
"condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
"shortcuts": "((strikethrough))",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"wrap-selection\"\n\tprefix=\"~~\"\n\tsuffix=\"~~\"\n/>\n"
},
"$:/core/ui/EditorToolbar/subscript": {
"title": "$:/core/ui/EditorToolbar/subscript",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/subscript",
"caption": "{{$:/language/Buttons/Subscript/Caption}}",
"description": "{{$:/language/Buttons/Subscript/Hint}}",
"condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
"shortcuts": "((subscript))",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"wrap-selection\"\n\tprefix=\",,\"\n\tsuffix=\",,\"\n/>\n"
},
"$:/core/ui/EditorToolbar/superscript": {
"title": "$:/core/ui/EditorToolbar/superscript",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/superscript",
"caption": "{{$:/language/Buttons/Superscript/Caption}}",
"description": "{{$:/language/Buttons/Superscript/Hint}}",
"condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
"shortcuts": "((superscript))",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"wrap-selection\"\n\tprefix=\"^^\"\n\tsuffix=\"^^\"\n/>\n"
},
"$:/core/ui/EditorToolbar/transcludify": {
"title": "$:/core/ui/EditorToolbar/transcludify",
"caption": "{{$:/language/Buttons/Transcludify/Caption}}",
"condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
"description": "{{$:/language/Buttons/Transcludify/Hint}}",
"icon": "$:/core/images/transcludify",
"list-before": "$:/core/ui/EditorToolbar/mono-block",
"shortcuts": "((transcludify))",
"tags": "$:/tags/EditorToolbar",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"wrap-selection\"\n\tprefix=\"{{\"\n\tsuffix=\"}}\"\n/>\n"
},
"$:/core/ui/EditorToolbar/underline": {
"title": "$:/core/ui/EditorToolbar/underline",
"tags": "$:/tags/EditorToolbar",
"icon": "$:/core/images/underline",
"caption": "{{$:/language/Buttons/Underline/Caption}}",
"description": "{{$:/language/Buttons/Underline/Hint}}",
"condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
"shortcuts": "((underline))",
"text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"wrap-selection\"\n\tprefix=\"__\"\n\tsuffix=\"__\"\n/>\n"
},
"$:/core/Filters/AllTags": {
"title": "$:/core/Filters/AllTags",
"tags": "$:/tags/Filter",
"filter": "[tags[]!is[system]sort[title]]",
"description": "{{$:/language/Filters/AllTags}}",
"text": ""
},
"$:/core/Filters/AllTiddlers": {
"title": "$:/core/Filters/AllTiddlers",
"tags": "$:/tags/Filter",
"filter": "[!is[system]sort[title]]",
"description": "{{$:/language/Filters/AllTiddlers}}",
"text": ""
},
"$:/core/Filters/Drafts": {
"title": "$:/core/Filters/Drafts",
"tags": "$:/tags/Filter",
"filter": "[has[draft.of]sort[title]]",
"description": "{{$:/language/Filters/Drafts}}",
"text": ""
},
"$:/core/Filters/Missing": {
"title": "$:/core/Filters/Missing",
"tags": "$:/tags/Filter",
"filter": "[all[missing]sort[title]]",
"description": "{{$:/language/Filters/Missing}}",
"text": ""
},
"$:/core/Filters/Orphans": {
"title": "$:/core/Filters/Orphans",
"tags": "$:/tags/Filter",
"filter": "[all[orphans]sort[title]]",
"description": "{{$:/language/Filters/Orphans}}",
"text": ""
},
"$:/core/Filters/OverriddenShadowTiddlers": {
"title": "$:/core/Filters/OverriddenShadowTiddlers",
"tags": "$:/tags/Filter",
"filter": "[is[shadow]]",
"description": "{{$:/language/Filters/OverriddenShadowTiddlers}}",
"text": ""
},
"$:/core/Filters/RecentSystemTiddlers": {
"title": "$:/core/Filters/RecentSystemTiddlers",
"tags": "$:/tags/Filter",
"filter": "[has[modified]!sort[modified]limit[50]]",
"description": "{{$:/language/Filters/RecentSystemTiddlers}}",
"text": ""
},
"$:/core/Filters/RecentTiddlers": {
"title": "$:/core/Filters/RecentTiddlers",
"tags": "$:/tags/Filter",
"filter": "[!is[system]has[modified]!sort[modified]limit[50]]",
"description": "{{$:/language/Filters/RecentTiddlers}}",
"text": ""
},
"$:/core/Filters/ShadowTiddlers": {
"title": "$:/core/Filters/ShadowTiddlers",
"tags": "$:/tags/Filter",
"filter": "[all[shadows]sort[title]]",
"description": "{{$:/language/Filters/ShadowTiddlers}}",
"text": ""
},
"$:/core/Filters/StoryList": {
"title": "$:/core/Filters/StoryList",
"tags": "$:/tags/Filter",
"filter": "[list[$:/StoryList]] -$:/AdvancedSearch",
"description": "{{$:/language/Filters/StoryList}}",
"text": ""
},
"$:/core/Filters/SystemTags": {
"title": "$:/core/Filters/SystemTags",
"tags": "$:/tags/Filter",
"filter": "[all[shadows+tiddlers]tags[]is[system]sort[title]]",
"description": "{{$:/language/Filters/SystemTags}}",
"text": ""
},
"$:/core/Filters/SystemTiddlers": {
"title": "$:/core/Filters/SystemTiddlers",
"tags": "$:/tags/Filter",
"filter": "[is[system]sort[title]]",
"description": "{{$:/language/Filters/SystemTiddlers}}",
"text": ""
},
"$:/core/Filters/TypedTiddlers": {
"title": "$:/core/Filters/TypedTiddlers",
"tags": "$:/tags/Filter",
"filter": "[!is[system]has[type]each[type]sort[type]] -[type[text/vnd.tiddlywiki]]",
"description": "{{$:/language/Filters/TypedTiddlers}}",
"text": ""
},
"$:/core/ui/ImportListing": {
"title": "$:/core/ui/ImportListing",
"text": "\\define lingo-base() $:/language/Import/\n\n\\define messageField()\nmessage-$(payloadTiddler)$\n\\end\n\n\\define selectionField()\nselection-$(payloadTiddler)$\n\\end\n\n\\define previewPopupState()\n$(currentTiddler)$!!popup-$(payloadTiddler)$\n\\end\n\n\\define select-all-actions()\n<$list filter=\"[all[current]plugintiddlers[]sort[title]]\" variable=\"payloadTiddler\">\n<$action-setfield $field={{{ [<payloadTiddler>addprefix[selection-]] }}} $value={{$:/state/import/select-all}}/>\n</$list>\n\\end\n\n<table>\n<tbody>\n<tr>\n<th>\n<$checkbox tiddler=\"$:/state/import/select-all\" field=\"text\" checked=\"checked\" unchecked=\"unchecked\" default=\"checked\" actions=<<select-all-actions>>>\n<<lingo Listing/Select/Caption>>\n</$checkbox>\n</th>\n<th>\n<<lingo Listing/Title/Caption>>\n</th>\n<th>\n<<lingo Listing/Status/Caption>>\n</th>\n</tr>\n<$list filter=\"[all[current]plugintiddlers[]sort[title]]\" variable=\"payloadTiddler\">\n<tr>\n<td>\n<$checkbox field=<<selectionField>> checked=\"checked\" unchecked=\"unchecked\" default=\"checked\"/>\n</td>\n<td>\n<$reveal type=\"nomatch\" stateTitle=<<previewPopupState>> text=\"yes\" tag=\"div\">\n<$button class=\"tc-btn-invisible tc-btn-dropdown\" setTitle=<<previewPopupState>> setTo=\"yes\">\n{{$:/core/images/right-arrow}} <$text text=<<payloadTiddler>>/>\n</$button>\n</$reveal>\n<$reveal type=\"match\" stateTitle=<<previewPopupState>> text=\"yes\" tag=\"div\">\n<$button class=\"tc-btn-invisible tc-btn-dropdown\" setTitle=<<previewPopupState>> setTo=\"no\">\n{{$:/core/images/down-arrow}} <$text text=<<payloadTiddler>>/>\n</$button>\n</$reveal>\n</td>\n<td>\n<$view field=<<messageField>>/>\n</td>\n</tr>\n<tr>\n<td colspan=\"3\">\n<$reveal type=\"match\" text=\"yes\" stateTitle=<<previewPopupState>> tag=\"div\">\n<$list filter=\"[{$:/state/importpreviewtype}has[text]]\" variable=\"listItem\" emptyMessage={{$:/core/ui/ImportPreviews/Text}}>\n<$transclude tiddler={{$:/state/importpreviewtype}}/>\n</$list>\n</$reveal>\n</td>\n</tr>\n</$list>\n</tbody>\n</table>\n"
},
"$:/core/ui/ImportPreviews/Diff": {
"title": "$:/core/ui/ImportPreviews/Diff",
"tags": "$:/tags/ImportPreview",
"caption": "{{$:/language/Import/Listing/Preview/Diff}}",
"text": "<$macrocall $name=\"compareTiddlerText\" sourceTiddlerTitle=<<payloadTiddler>> destTiddlerTitle=<<currentTiddler>> destSubTiddlerTitle=<<payloadTiddler>>/>\n"
},
"$:/core/ui/ImportPreviews/DiffFields": {
"title": "$:/core/ui/ImportPreviews/DiffFields",
"tags": "$:/tags/ImportPreview",
"caption": "{{$:/language/Import/Listing/Preview/DiffFields}}",
"text": "<$macrocall $name=\"compareTiddlers\" sourceTiddlerTitle=<<payloadTiddler>> destTiddlerTitle=<<currentTiddler>> destSubTiddlerTitle=<<payloadTiddler>> exclude=\"text\"/>\n"
},
"$:/core/ui/ImportPreviews/Fields": {
"title": "$:/core/ui/ImportPreviews/Fields",
"tags": "$:/tags/ImportPreview",
"caption": "{{$:/language/Import/Listing/Preview/Fields}}",
"text": "<table class=\"tc-view-field-table\">\n<tbody>\n<$list filter=\"[<payloadTiddler>subtiddlerfields<currentTiddler>sort[]] -text\" variable=\"fieldName\">\n<tr class=\"tc-view-field\">\n<td class=\"tc-view-field-name\">\n<$text text=<<fieldName>>/>\n</td>\n<td class=\"tc-view-field-value\">\n<$view field=<<fieldName>> tiddler=<<currentTiddler>> subtiddler=<<payloadTiddler>>/>\n</td>\n</tr>\n</$list>\n</tbody>\n</table>\n"
},
"$:/core/ui/ImportPreviews/Text": {
"title": "$:/core/ui/ImportPreviews/Text",
"tags": "$:/tags/ImportPreview",
"caption": "{{$:/language/Import/Listing/Preview/Text}}",
"text": "<$transclude tiddler=<<currentTiddler>> subtiddler=<<payloadTiddler>> mode=\"block\"/>\n"
},
"$:/core/ui/ImportPreviews/TextRaw": {
"title": "$:/core/ui/ImportPreviews/TextRaw",
"tags": "$:/tags/ImportPreview",
"caption": "{{$:/language/Import/Listing/Preview/TextRaw}}",
"text": "<pre><code><$view tiddler=<<currentTiddler>> subtiddler=<<payloadTiddler>> /></code></pre>"
},
"$:/core/ui/KeyboardShortcuts/new-image": {
"title": "$:/core/ui/KeyboardShortcuts/new-image",
"tags": "$:/tags/KeyboardShortcut",
"key": "((new-image))",
"text": "<$navigator story=\"$:/StoryList\" history=\"$:/HistoryList\" openLinkFromInsideRiver={{$:/config/Navigation/openLinkFromInsideRiver}} openLinkFromOutsideRiver={{$:/config/Navigation/openLinkFromOutsideRiver}} relinkOnRename={{$:/config/RelinkOnRename}}>\n{{$:/core/ui/Actions/new-image}}\n</$navigator>\n"
},
"$:/core/ui/KeyboardShortcuts/new-journal": {
"title": "$:/core/ui/KeyboardShortcuts/new-journal",
"tags": "$:/tags/KeyboardShortcut",
"key": "((new-journal))",
"text": "<$navigator story=\"$:/StoryList\" history=\"$:/HistoryList\" openLinkFromInsideRiver={{$:/config/Navigation/openLinkFromInsideRiver}} openLinkFromOutsideRiver={{$:/config/Navigation/openLinkFromOutsideRiver}} relinkOnRename={{$:/config/RelinkOnRename}}>\n{{$:/core/ui/Actions/new-journal}}\n</$navigator>\n"
},
"$:/core/ui/KeyboardShortcuts/new-tiddler": {
"title": "$:/core/ui/KeyboardShortcuts/new-tiddler",
"tags": "$:/tags/KeyboardShortcut",
"key": "((new-tiddler))",
"text": "<$navigator story=\"$:/StoryList\" history=\"$:/HistoryList\" openLinkFromInsideRiver={{$:/config/Navigation/openLinkFromInsideRiver}} openLinkFromOutsideRiver={{$:/config/Navigation/openLinkFromOutsideRiver}} relinkOnRename={{$:/config/RelinkOnRename}}>\n{{$:/core/ui/Actions/new-tiddler}}\n</$navigator>\n"
},
"$:/core/ui/ListItemTemplate": {
"title": "$:/core/ui/ListItemTemplate",
"text": "<div class=\"tc-menu-list-item\">\n<$link to={{!!title}}>\n<$view field=\"title\"/>\n</$link>\n</div>"
},
"$:/Manager/ItemMain/Fields": {
"title": "$:/Manager/ItemMain/Fields",
"tags": "$:/tags/Manager/ItemMain",
"caption": "{{$:/language/Manager/Item/Fields}}",
"text": "<table>\n<tbody>\n<$list filter=\"[all[current]fields[]sort[title]] -text\" template=\"$:/core/ui/TiddlerFieldTemplate\" variable=\"listItem\"/>\n</tbody>\n</table>\n"
},
"$:/Manager/ItemMain/RawText": {
"title": "$:/Manager/ItemMain/RawText",
"tags": "$:/tags/Manager/ItemMain",
"caption": "{{$:/language/Manager/Item/RawText}}",
"text": "<pre><code><$view/></code></pre>\n"
},
"$:/Manager/ItemMain/WikifiedText": {
"title": "$:/Manager/ItemMain/WikifiedText",
"tags": "$:/tags/Manager/ItemMain",
"caption": "{{$:/language/Manager/Item/WikifiedText}}",
"text": "<$transclude mode=\"block\"/>\n"
},
"$:/Manager/ItemSidebar/Colour": {
"title": "$:/Manager/ItemSidebar/Colour",
"tags": "$:/tags/Manager/ItemSidebar",
"caption": "{{$:/language/Manager/Item/Colour}}",
"text": "\\define swatch-styles()\nheight: 1em;\nbackground-color: $(colour)$\n\\end\n\n<$vars colour={{!!color}}>\n<p style=<<swatch-styles>>/>\n</$vars>\n<p>\n<$edit-text field=\"color\" tag=\"input\" type=\"color\"/> / <$edit-text field=\"color\" tag=\"input\" type=\"text\" size=\"9\"/>\n</p>\n"
},
"$:/Manager/ItemSidebar/Icon": {
"title": "$:/Manager/ItemSidebar/Icon",
"tags": "$:/tags/Manager/ItemSidebar",
"caption": "{{$:/language/Manager/Item/Icon}}",
"text": "<p>\n<div class=\"tc-manager-icon-editor\">\n<$button popup=<<qualify \"$:/state/popup/image-picker\">> class=\"tc-btn-invisible\">\n<$transclude tiddler={{!!icon}}>\n{{$:/language/Manager/Item/Icon/None}}\n</$transclude>\n</$button>\n<div class=\"tc-block-dropdown-wrapper\" style=\"position: static;\">\n<$reveal state=<<qualify \"$:/state/popup/image-picker\">> type=\"nomatch\" text=\"\" default=\"\" tag=\"div\" class=\"tc-popup\">\n<div class=\"tc-block-dropdown tc-popup-keep\" style=\"width: 80%; left: 10%; right: 10%; padding: 0.5em;\">\n<$macrocall $name=\"image-picker-include-tagged-images\" actions=\"\"\"\n<$action-setfield $field=\"icon\" $value=<<imageTitle>>/>\n<$action-deletetiddler $tiddler=<<qualify \"$:/state/popup/image-picker\">>/>\n\"\"\"/>\n</div>\n</$reveal>\n</div>\n</div>\n</p>\n"
},
"$:/Manager/ItemSidebar/Tags": {
"title": "$:/Manager/ItemSidebar/Tags",
"tags": "$:/tags/Manager/ItemSidebar",
"caption": "{{$:/language/Manager/Item/Tags}}",
"text": "\\define tag-checkbox-actions()\n<$action-listops\n\t$tiddler=\"$:/config/Manager/RecentTags\"\n\t$subfilter=\"[<tag>] [list[$:/config/Manager/RecentTags]] +[limit[12]]\"\n/>\n\\end\n\n\\define tag-picker-actions()\n<<tag-checkbox-actions>>\n<$action-listops\n\t$tiddler=<<currentTiddler>>\n\t$field=\"tags\"\n\t$subfilter=\"[<tag>] [all[current]tags[]]\"\n/>\n\\end\n\n<p>\n<$list filter=\"[all[current]tags[]] [list[$:/config/Manager/RecentTags]] +[sort[title]] \" variable=\"tag\">\n<div>\n<$checkbox tiddler=<<currentTiddler>> tag=<<tag>> actions=<<tag-checkbox-actions>>>\n<$macrocall $name=\"tag-pill\" tag=<<tag>>/>\n</$checkbox>\n</div>\n</$list>\n</p>\n<p>\n<$macrocall $name=\"tag-picker\" actions=<<tag-picker-actions>>/>\n</p>\n"
},
"$:/Manager/ItemSidebar/Tools": {
"title": "$:/Manager/ItemSidebar/Tools",
"tags": "$:/tags/Manager/ItemSidebar",
"caption": "{{$:/language/Manager/Item/Tools}}",
"text": "<p>\n<$button to=<<currentTiddler>>>{{$:/core/images/link}} open</$button>\n</p>\n<p>\n<$button message=\"tm-edit-tiddler\" param=<<currentTiddler>>>{{$:/core/images/edit-button}} edit</$button>\n</p>\n"
},
"$:/Manager": {
"title": "$:/Manager",
"icon": "$:/core/images/list",
"color": "#bbb",
"text": "\\define lingo-base() $:/language/Manager/\n\n\\define list-item-content-item()\n<div class=\"tc-manager-list-item-content-item\">\n\t<$vars state-title=\"\"\"$:/state/popup/manager/item/$(listItem)$\"\"\">\n\t\t<$reveal state=<<state-title>> type=\"match\" text=\"show\" default=\"show\" tag=\"div\">\n\t\t\t<$button set=<<state-title>> setTo=\"hide\" class=\"tc-btn-invisible tc-manager-list-item-content-item-heading\">\n\t\t\t\t{{$:/core/images/down-arrow}} <$transclude tiddler=<<listItem>> field=\"caption\"/>\n\t\t\t</$button>\n\t\t</$reveal>\n\t\t<$reveal state=<<state-title>> type=\"nomatch\" text=\"show\" default=\"show\" tag=\"div\">\n\t\t\t<$button set=<<state-title>> setTo=\"show\" class=\"tc-btn-invisible tc-manager-list-item-content-item-heading\">\n\t\t\t\t{{$:/core/images/right-arrow}} <$transclude tiddler=<<listItem>> field=\"caption\"/>\n\t\t\t</$button>\n\t\t</$reveal>\n\t\t<$reveal state=<<state-title>> type=\"match\" text=\"show\" default=\"show\" tag=\"div\" class=\"tc-manager-list-item-content-item-body\">\n\t\t\t<$transclude tiddler=<<listItem>>/>\n\t\t</$reveal>\n\t</$vars>\n</div>\n\\end\n\n<div class=\"tc-manager-wrapper\">\n\t<div class=\"tc-manager-controls\">\n\t\t<div class=\"tc-manager-control\">\n\t\t\t<<lingo Controls/Show/Prompt>> <$select tiddler=\"$:/config/Manager/Show\" default=\"tiddlers\">\n\t\t\t\t<option value=\"tiddlers\"><<lingo Controls/Show/Option/Tiddlers>></option>\n\t\t\t\t<option value=\"tags\"><<lingo Controls/Show/Option/Tags>></option>\n\t\t\t</$select>\n\t\t</div>\n\t\t<div class=\"tc-manager-control\">\n\t\t\t<<lingo Controls/Search/Prompt>> <$edit-text tiddler=\"$:/config/Manager/Filter\" tag=\"input\" default=\"\" placeholder={{$:/language/Manager/Controls/Search/Placeholder}}/>\n\t\t</div>\n\t\t<div class=\"tc-manager-control\">\n\t\t\t<<lingo Controls/FilterByTag/Prompt>> <$select tiddler=\"$:/config/Manager/Tag\" default=\"\">\n\t\t\t\t<option value=\"\"><<lingo Controls/FilterByTag/None>></option>\n\t\t\t\t<$list filter=\"[!is{$:/config/Manager/System}tags[]!is[system]sort[title]]\" variable=\"tag\">\n\t\t\t\t\t<option value=<<tag>>><$text text=<<tag>>/></option>\n\t\t\t\t</$list>\n\t\t\t</$select>\n\t\t</div>\n\t\t<div class=\"tc-manager-control\">\n\t\t\t<<lingo Controls/Sort/Prompt>> <$select tiddler=\"$:/config/Manager/Sort\" default=\"title\">\n\t\t\t\t<optgroup label=\"Common\">\n\t\t\t\t\t<$list filter=\"title modified modifier created creator created\" variable=\"field\">\n\t\t\t\t\t\t<option value=<<field>>><$text text=<<field>>/></option>\n\t\t\t\t\t</$list>\n\t\t\t\t</optgroup>\n\t\t\t\t<optgroup label=\"All\">\n\t\t\t\t\t<$list filter=\"[all{$:/config/Manager/Show}!is{$:/config/Manager/System}fields[]sort[title]] -title -modified -modifier -created -creator -created\" variable=\"field\">\n\t\t\t\t\t\t<option value=<<field>>><$text text=<<field>>/></option>\n\t\t\t\t\t</$list>\n\t\t\t\t</optgroup>\n\t\t\t</$select>\n\t\t\t<$checkbox tiddler=\"$:/config/Manager/Order\" field=\"text\" checked=\"reverse\" unchecked=\"forward\" default=\"forward\">\n\t\t\t\t<<lingo Controls/Order/Prompt>>\n\t\t\t</$checkbox>\n\t\t</div>\n\t\t<div class=\"tc-manager-control\">\n\t\t\t<$checkbox tiddler=\"$:/config/Manager/System\" field=\"text\" checked=\"\" unchecked=\"system\" default=\"system\">\n\t\t\t\t{{$:/language/SystemTiddlers/Include/Prompt}}\n\t\t\t</$checkbox>\n\t\t</div>\n\t</div>\n\t<div class=\"tc-manager-list\">\n\t\t<$list filter=\"[all{$:/config/Manager/Show}!is{$:/config/Manager/System}search{$:/config/Manager/Filter}tag:strict{$:/config/Manager/Tag}sort{$:/config/Manager/Sort}order{$:/config/Manager/Order}]\">\n\t\t\t<$vars transclusion=<<currentTiddler>>>\n\t\t\t\t<div style=\"tc-manager-list-item\">\n\t\t\t\t\t<$button popup=<<qualify \"$:/state/manager/popup\">> class=\"tc-btn-invisible tc-manager-list-item-heading\" selectedClass=\"tc-manager-list-item-heading-selected\">\n\t\t\t\t\t\t<$text text=<<currentTiddler>>/>\n\t\t\t\t\t</$button>\n\t\t\t\t\t<$reveal state=<<qualify \"$:/state/manager/popup\">> type=\"nomatch\" text=\"\" default=\"\" tag=\"div\" class=\"tc-manager-list-item-content tc-popup-handle\">\n\t\t\t\t\t\t<div class=\"tc-manager-list-item-content-tiddler\">\n\t\t\t\t\t\t\t<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/Manager/ItemMain]!has[draft.of]]\" variable=\"listItem\">\n\t\t\t\t\t\t\t\t<<list-item-content-item>>\n\t\t\t\t\t\t\t</$list>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div class=\"tc-manager-list-item-content-sidebar\">\n\t\t\t\t\t\t\t<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/Manager/ItemSidebar]!has[draft.of]]\" variable=\"listItem\">\n\t\t\t\t\t\t\t\t<<list-item-content-item>>\n\t\t\t\t\t\t\t</$list>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</$reveal>\n\t\t\t\t</div>\n\t\t\t</$vars>\n\t\t</$list>\n\t</div>\n</div>\n"
},
"$:/core/ui/MissingTemplate": {
"title": "$:/core/ui/MissingTemplate",
"text": "<div class=\"tc-tiddler-missing\">\n<$button popup=<<qualify \"$:/state/popup/missing\">> class=\"tc-btn-invisible tc-missing-tiddler-label\">\n<$view field=\"title\" format=\"text\" />\n</$button>\n<$reveal state=<<qualify \"$:/state/popup/missing\">> type=\"popup\" position=\"below\" animate=\"yes\">\n<div class=\"tc-drop-down\">\n<$transclude tiddler=\"$:/core/ui/ListItemTemplate\"/>\n<hr>\n<$list filter=\"[all[current]backlinks[]sort[title]]\" template=\"$:/core/ui/ListItemTemplate\"/>\n</div>\n</$reveal>\n</div>\n"
},
"$:/core/ui/MoreSideBar/All": {
"title": "$:/core/ui/MoreSideBar/All",
"tags": "$:/tags/MoreSideBar",
"caption": "{{$:/language/SideBar/All/Caption}}",
"text": "<$list filter={{$:/core/Filters/AllTiddlers!!filter}} template=\"$:/core/ui/ListItemTemplate\"/>\n"
},
"$:/core/ui/MoreSideBar/Drafts": {
"title": "$:/core/ui/MoreSideBar/Drafts",
"tags": "$:/tags/MoreSideBar",
"caption": "{{$:/language/SideBar/Drafts/Caption}}",
"text": "<$list filter={{$:/core/Filters/Drafts!!filter}} template=\"$:/core/ui/ListItemTemplate\"/>\n"
},
"$:/core/ui/MoreSideBar/Explorer": {
"title": "$:/core/ui/MoreSideBar/Explorer",
"tags": "$:/tags/MoreSideBar",
"caption": "{{$:/language/SideBar/Explorer/Caption}}",
"text": "<<tree \"$:/\">>\n"
},
"$:/core/ui/MoreSideBar/Missing": {
"title": "$:/core/ui/MoreSideBar/Missing",
"tags": "$:/tags/MoreSideBar",
"caption": "{{$:/language/SideBar/Missing/Caption}}",
"text": "<$list filter={{$:/core/Filters/Missing!!filter}} template=\"$:/core/ui/MissingTemplate\"/>\n"
},
"$:/core/ui/MoreSideBar/Orphans": {
"title": "$:/core/ui/MoreSideBar/Orphans",
"tags": "$:/tags/MoreSideBar",
"caption": "{{$:/language/SideBar/Orphans/Caption}}",
"text": "<$list filter={{$:/core/Filters/Orphans!!filter}} template=\"$:/core/ui/ListItemTemplate\"/>\n"
},
"$:/core/ui/MoreSideBar/Plugins": {
"title": "$:/core/ui/MoreSideBar/Plugins",
"tags": "$:/tags/MoreSideBar",
"caption": "{{$:/language/ControlPanel/Plugins/Caption}}",
"text": "\n{{$:/language/ControlPanel/Plugins/Installed/Hint}}\n\n<<tabs \"[all[shadows+tiddlers]tag[$:/tags/MoreSideBar/Plugins]!has[draft.of]]\" \"$:/core/ui/MoreSideBar/Plugins/Plugins\">>\n"
},
"$:/core/ui/MoreSideBar/Recent": {
"title": "$:/core/ui/MoreSideBar/Recent",
"tags": "$:/tags/MoreSideBar",
"caption": "{{$:/language/SideBar/Recent/Caption}}",
"text": "<$macrocall $name=\"timeline\" format={{$:/language/RecentChanges/DateFormat}}/>\n"
},
"$:/core/ui/MoreSideBar/Shadows": {
"title": "$:/core/ui/MoreSideBar/Shadows",
"tags": "$:/tags/MoreSideBar",
"caption": "{{$:/language/SideBar/Shadows/Caption}}",
"text": "<$list filter={{$:/core/Filters/ShadowTiddlers!!filter}} template=\"$:/core/ui/ListItemTemplate\"/>\n"
},
"$:/core/ui/MoreSideBar/System": {
"title": "$:/core/ui/MoreSideBar/System",
"tags": "$:/tags/MoreSideBar",
"caption": "{{$:/language/SideBar/System/Caption}}",
"text": "<$list filter={{$:/core/Filters/SystemTiddlers!!filter}} template=\"$:/core/ui/ListItemTemplate\"/>\n"
},
"$:/core/ui/MoreSideBar/Tags": {
"title": "$:/core/ui/MoreSideBar/Tags",
"tags": "$:/tags/MoreSideBar",
"caption": "{{$:/language/SideBar/Tags/Caption}}",
"text": "<$set name=\"tv-config-toolbar-icons\" value=\"yes\">\n\n<$set name=\"tv-config-toolbar-text\" value=\"yes\">\n\n<$set name=\"tv-config-toolbar-class\" value=\"\">\n\n{{$:/core/ui/Buttons/tag-manager}}\n\n</$set>\n\n</$set>\n\n</$set>\n\n<$list filter={{$:/core/Filters/AllTags!!filter}}>\n\n<$transclude tiddler=\"$:/core/ui/TagTemplate\"/>\n\n</$list>\n\n<hr class=\"tc-untagged-separator\">\n\n{{$:/core/ui/UntaggedTemplate}}\n"
},
"$:/core/ui/MoreSideBar/Types": {
"title": "$:/core/ui/MoreSideBar/Types",
"tags": "$:/tags/MoreSideBar",
"caption": "{{$:/language/SideBar/Types/Caption}}",
"text": "<$list filter={{$:/core/Filters/TypedTiddlers!!filter}}>\n<div class=\"tc-menu-list-item\">\n<$view field=\"type\"/>\n<$list filter=\"[type{!!type}!is[system]sort[title]]\">\n<div class=\"tc-menu-list-subitem\">\n<$link to={{!!title}}><$view field=\"title\"/></$link>\n</div>\n</$list>\n</div>\n</$list>\n"
},
"$:/core/ui/MoreSideBar/Plugins/Languages": {
"title": "$:/core/ui/MoreSideBar/Plugins/Languages",
"tags": "$:/tags/MoreSideBar/Plugins",
"caption": "{{$:/language/ControlPanel/Plugins/Languages/Caption}}",
"text": "<$list filter=\"[!has[draft.of]plugin-type[language]sort[description]]\" template=\"$:/core/ui/PluginListItemTemplate\" emptyMessage={{$:/language/ControlPanel/Plugins/Empty/Hint}}/>\n"
},
"$:/core/ui/MoreSideBar/Plugins/Plugins": {
"title": "$:/core/ui/MoreSideBar/Plugins/Plugins",
"tags": "$:/tags/MoreSideBar/Plugins",
"caption": "{{$:/language/ControlPanel/Plugins/Plugins/Caption}}",
"text": "<$list filter=\"[!has[draft.of]plugin-type[plugin]sort[description]]\" template=\"$:/core/ui/PluginListItemTemplate\" emptyMessage={{$:/language/ControlPanel/Plugins/Empty/Hint}}>>/>\n"
},
"$:/core/ui/MoreSideBar/Plugins/Theme": {
"title": "$:/core/ui/MoreSideBar/Plugins/Theme",
"tags": "$:/tags/MoreSideBar/Plugins",
"caption": "{{$:/language/ControlPanel/Plugins/Themes/Caption}}",
"text": "<$list filter=\"[!has[draft.of]plugin-type[theme]sort[description]]\" template=\"$:/core/ui/PluginListItemTemplate\" emptyMessage={{$:/language/ControlPanel/Plugins/Empty/Hint}}/>\n"
},
"$:/core/ui/Buttons/advanced-search": {
"title": "$:/core/ui/Buttons/advanced-search",
"tags": "$:/tags/PageControls",
"caption": "{{$:/core/images/advanced-search-button}} {{$:/language/Buttons/AdvancedSearch/Caption}}",
"description": "{{$:/language/Buttons/AdvancedSearch/Hint}}",
"text": "\\define control-panel-button(class)\n<$button to=\"$:/AdvancedSearch\" tooltip={{$:/language/Buttons/AdvancedSearch/Hint}} aria-label={{$:/language/Buttons/AdvancedSearch/Caption}} class=\"\"\"$(tv-config-toolbar-class)$ $class$\"\"\">\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/advanced-search-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/AdvancedSearch/Caption}}/></span>\n</$list>\n</$button>\n\\end\n\n<$list filter=\"[list[$:/StoryList]] +[field:title[$:/AdvancedSearch]]\" emptyMessage=<<control-panel-button>>>\n<<control-panel-button \"tc-selected\">>\n</$list>\n"
},
"$:/core/ui/Buttons/close-all": {
"title": "$:/core/ui/Buttons/close-all",
"tags": "$:/tags/PageControls",
"caption": "{{$:/core/images/close-all-button}} {{$:/language/Buttons/CloseAll/Caption}}",
"description": "{{$:/language/Buttons/CloseAll/Hint}}",
"text": "<$button message=\"tm-close-all-tiddlers\" tooltip={{$:/language/Buttons/CloseAll/Hint}} aria-label={{$:/language/Buttons/CloseAll/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/close-all-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/CloseAll/Caption}}/></span>\n</$list>\n</$button>"
},
"$:/core/ui/Buttons/control-panel": {
"title": "$:/core/ui/Buttons/control-panel",
"tags": "$:/tags/PageControls",
"caption": "{{$:/core/images/options-button}} {{$:/language/Buttons/ControlPanel/Caption}}",
"description": "{{$:/language/Buttons/ControlPanel/Hint}}",
"text": "\\define control-panel-button(class)\n<$button to=\"$:/ControlPanel\" tooltip={{$:/language/Buttons/ControlPanel/Hint}} aria-label={{$:/language/Buttons/ControlPanel/Caption}} class=\"\"\"$(tv-config-toolbar-class)$ $class$\"\"\">\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/options-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/ControlPanel/Caption}}/></span>\n</$list>\n</$button>\n\\end\n\n<$list filter=\"[list[$:/StoryList]] +[field:title[$:/ControlPanel]]\" emptyMessage=<<control-panel-button>>>\n<<control-panel-button \"tc-selected\">>\n</$list>\n"
},
"$:/core/ui/Buttons/encryption": {
"title": "$:/core/ui/Buttons/encryption",
"tags": "$:/tags/PageControls",
"caption": "{{$:/core/images/locked-padlock}} {{$:/language/Buttons/Encryption/Caption}}",
"description": "{{$:/language/Buttons/Encryption/Hint}}",
"text": "<$reveal type=\"match\" state=\"$:/isEncrypted\" text=\"yes\">\n<$button message=\"tm-clear-password\" tooltip={{$:/language/Buttons/Encryption/ClearPassword/Hint}} aria-label={{$:/language/Buttons/Encryption/ClearPassword/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/locked-padlock}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Encryption/ClearPassword/Caption}}/></span>\n</$list>\n</$button>\n</$reveal>\n<$reveal type=\"nomatch\" state=\"$:/isEncrypted\" text=\"yes\">\n<$button message=\"tm-set-password\" tooltip={{$:/language/Buttons/Encryption/SetPassword/Hint}} aria-label={{$:/language/Buttons/Encryption/SetPassword/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/unlocked-padlock}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Encryption/SetPassword/Caption}}/></span>\n</$list>\n</$button>\n</$reveal>"
},
"$:/core/ui/Buttons/export-page": {
"title": "$:/core/ui/Buttons/export-page",
"tags": "$:/tags/PageControls",
"caption": "{{$:/core/images/export-button}} {{$:/language/Buttons/ExportPage/Caption}}",
"description": "{{$:/language/Buttons/ExportPage/Hint}}",
"text": "<$macrocall $name=\"exportButton\" exportFilter=\"[!is[system]sort[title]]\" lingoBase=\"$:/language/Buttons/ExportPage/\"/>"
},
"$:/core/ui/Buttons/fold-all": {
"title": "$:/core/ui/Buttons/fold-all",
"tags": "$:/tags/PageControls",
"caption": "{{$:/core/images/fold-all-button}} {{$:/language/Buttons/FoldAll/Caption}}",
"description": "{{$:/language/Buttons/FoldAll/Hint}}",
"text": "<$button tooltip={{$:/language/Buttons/FoldAll/Hint}} aria-label={{$:/language/Buttons/FoldAll/Caption}} class=<<tv-config-toolbar-class>>>\n<$action-sendmessage $message=\"tm-fold-all-tiddlers\" $param=<<currentTiddler>> foldedStatePrefix=\"$:/state/folded/\"/>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\" variable=\"listItem\">\n{{$:/core/images/fold-all-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/FoldAll/Caption}}/></span>\n</$list>\n</$button>"
},
"$:/core/ui/Buttons/full-screen": {
"title": "$:/core/ui/Buttons/full-screen",
"tags": "$:/tags/PageControls",
"caption": "{{$:/core/images/full-screen-button}} {{$:/language/Buttons/FullScreen/Caption}}",
"description": "{{$:/language/Buttons/FullScreen/Hint}}",
"text": "<$button message=\"tm-full-screen\" tooltip={{$:/language/Buttons/FullScreen/Hint}} aria-label={{$:/language/Buttons/FullScreen/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/full-screen-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/FullScreen/Caption}}/></span>\n</$list>\n</$button>"
},
"$:/core/ui/Buttons/home": {
"title": "$:/core/ui/Buttons/home",
"tags": "$:/tags/PageControls",
"caption": "{{$:/core/images/home-button}} {{$:/language/Buttons/Home/Caption}}",
"description": "{{$:/language/Buttons/Home/Hint}}",
"text": "<$button message=\"tm-home\" tooltip={{$:/language/Buttons/Home/Hint}} aria-label={{$:/language/Buttons/Home/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/home-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Home/Caption}}/></span>\n</$list>\n</$button>"
},
"$:/core/ui/Buttons/import": {
"title": "$:/core/ui/Buttons/import",
"tags": "$:/tags/PageControls",
"caption": "{{$:/core/images/import-button}} {{$:/language/Buttons/Import/Caption}}",
"description": "{{$:/language/Buttons/Import/Hint}}",
"text": "<div class=\"tc-file-input-wrapper\">\n<$button tooltip={{$:/language/Buttons/Import/Hint}} aria-label={{$:/language/Buttons/Import/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/import-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Import/Caption}}/></span>\n</$list>\n</$button>\n<$browse tooltip={{$:/language/Buttons/Import/Hint}}/>\n</div>"
},
"$:/core/ui/Buttons/language": {
"title": "$:/core/ui/Buttons/language",
"tags": "$:/tags/PageControls",
"caption": "{{$:/core/images/globe}} {{$:/language/Buttons/Language/Caption}}",
"description": "{{$:/language/Buttons/Language/Hint}}",
"text": "\\define flag-title()\n$(languagePluginTitle)$/icon\n\\end\n<span class=\"tc-popup-keep\">\n<$button popup=<<qualify \"$:/state/popup/language\">> tooltip={{$:/language/Buttons/Language/Hint}} aria-label={{$:/language/Buttons/Language/Caption}} class=<<tv-config-toolbar-class>> selectedClass=\"tc-selected\">\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n<span class=\"tc-image-button\">\n<$set name=\"languagePluginTitle\" value={{$:/language}}>\n<$image source=<<flag-title>>/>\n</$set>\n</span>\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Language/Caption}}/></span>\n</$list>\n</$button>\n</span>\n<$reveal state=<<qualify \"$:/state/popup/language\">> type=\"popup\" position=\"below\" animate=\"yes\">\n<div class=\"tc-drop-down\">\n{{$:/snippets/languageswitcher}}\n</div>\n</$reveal>"
},
"$:/core/ui/Buttons/manager": {
"title": "$:/core/ui/Buttons/manager",
"tags": "$:/tags/PageControls",
"caption": "{{$:/core/images/list}} {{$:/language/Buttons/Manager/Caption}}",
"description": "{{$:/language/Buttons/Manager/Hint}}",
"text": "\\define manager-button(class)\n<$button to=\"$:/Manager\" tooltip={{$:/language/Buttons/Manager/Hint}} aria-label={{$:/language/Buttons/Manager/Caption}} class=\"\"\"$(tv-config-toolbar-class)$ $class$\"\"\">\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/list}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Manager/Caption}}/></span>\n</$list>\n</$button>\n\\end\n\n<$list filter=\"[list[$:/StoryList]] +[field:title[$:/Manager]]\" emptyMessage=<<manager-button>>>\n<<manager-button \"tc-selected\">>\n</$list>\n"
},
"$:/core/ui/Buttons/more-page-actions": {
"title": "$:/core/ui/Buttons/more-page-actions",
"tags": "$:/tags/PageControls",
"caption": "{{$:/core/images/down-arrow}} {{$:/language/Buttons/More/Caption}}",
"description": "{{$:/language/Buttons/More/Hint}}",
"text": "\\define config-title()\n$:/config/PageControlButtons/Visibility/$(listItem)$\n\\end\n<$button popup=<<qualify \"$:/state/popup/more\">> tooltip={{$:/language/Buttons/More/Hint}} aria-label={{$:/language/Buttons/More/Caption}} class=<<tv-config-toolbar-class>> selectedClass=\"tc-selected\">\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/down-arrow}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/More/Caption}}/></span>\n</$list>\n</$button><$reveal state=<<qualify \"$:/state/popup/more\">> type=\"popup\" position=\"below\" animate=\"yes\">\n\n<div class=\"tc-drop-down\">\n\n<$set name=\"tv-config-toolbar-icons\" value=\"yes\">\n\n<$set name=\"tv-config-toolbar-text\" value=\"yes\">\n\n<$set name=\"tv-config-toolbar-class\" value=\"tc-btn-invisible\">\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/PageControls]!has[draft.of]] -[[$:/core/ui/Buttons/more-page-actions]]\" variable=\"listItem\">\n\n<$reveal type=\"match\" state=<<config-title>> text=\"hide\">\n\n<$set name=\"tv-config-toolbar-class\" filter=\"[<tv-config-toolbar-class>] [<listItem>encodeuricomponent[]addprefix[tc-btn-]]\">\n\n<$transclude tiddler=<<listItem>> mode=\"inline\"/>\n\n</$set>\n\n</$reveal>\n\n</$list>\n\n</$set>\n\n</$set>\n\n</$set>\n\n</div>\n\n</$reveal>"
},
"$:/core/ui/Buttons/new-image": {
"title": "$:/core/ui/Buttons/new-image",
"tags": "$:/tags/PageControls",
"caption": "{{$:/core/images/new-image-button}} {{$:/language/Buttons/NewImage/Caption}}",
"description": "{{$:/language/Buttons/NewImage/Hint}}",
"text": "<$button tooltip={{$:/language/Buttons/NewImage/Hint}} aria-label={{$:/language/Buttons/NewImage/Caption}} class=<<tv-config-toolbar-class>> actions={{$:/core/ui/Actions/new-image}}>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/new-image-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/NewImage/Caption}}/></span>\n</$list>\n</$button>\n"
},
"$:/core/ui/Buttons/new-journal": {
"title": "$:/core/ui/Buttons/new-journal",
"tags": "$:/tags/PageControls",
"caption": "{{$:/core/images/new-journal-button}} {{$:/language/Buttons/NewJournal/Caption}}",
"description": "{{$:/language/Buttons/NewJournal/Hint}}",
"text": "\\define journalButton()\n<$button tooltip={{$:/language/Buttons/NewJournal/Hint}} aria-label={{$:/language/Buttons/NewJournal/Caption}} class=<<tv-config-toolbar-class>> actions={{$:/core/ui/Actions/new-journal}}>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/new-journal-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/NewJournal/Caption}}/></span>\n</$list>\n</$button>\n\\end\n<<journalButton>>\n"
},
"$:/core/ui/Buttons/new-tiddler": {
"title": "$:/core/ui/Buttons/new-tiddler",
"tags": "$:/tags/PageControls",
"caption": "{{$:/core/images/new-button}} {{$:/language/Buttons/NewTiddler/Caption}}",
"description": "{{$:/language/Buttons/NewTiddler/Hint}}",
"text": "<$button actions={{$:/core/ui/Actions/new-tiddler}} tooltip={{$:/language/Buttons/NewTiddler/Hint}} aria-label={{$:/language/Buttons/NewTiddler/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/new-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/NewTiddler/Caption}}/></span>\n</$list>\n</$button>\n"
},
"$:/core/ui/Buttons/palette": {
"title": "$:/core/ui/Buttons/palette",
"tags": "$:/tags/PageControls",
"caption": "{{$:/core/images/palette}} {{$:/language/Buttons/Palette/Caption}}",
"description": "{{$:/language/Buttons/Palette/Hint}}",
"text": "<span class=\"tc-popup-keep\">\n<$button popup=<<qualify \"$:/state/popup/palette\">> tooltip={{$:/language/Buttons/Palette/Hint}} aria-label={{$:/language/Buttons/Palette/Caption}} class=<<tv-config-toolbar-class>> selectedClass=\"tc-selected\">\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/palette}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Palette/Caption}}/></span>\n</$list>\n</$button>\n</span>\n<$reveal state=<<qualify \"$:/state/popup/palette\">> type=\"popup\" position=\"below\" animate=\"yes\">\n<div class=\"tc-drop-down\" style=\"font-size:0.7em;\">\n{{$:/snippets/paletteswitcher}}\n</div>\n</$reveal>"
},
"$:/core/ui/Buttons/print": {
"title": "$:/core/ui/Buttons/print",
"tags": "$:/tags/PageControls",
"caption": "{{$:/core/images/print-button}} {{$:/language/Buttons/Print/Caption}}",
"description": "{{$:/language/Buttons/Print/Hint}}",
"text": "<$button message=\"tm-print\" tooltip={{$:/language/Buttons/Print/Hint}} aria-label={{$:/language/Buttons/Print/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/print-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Print/Caption}}/></span>\n</$list>\n</$button>"
},
"$:/core/ui/Buttons/refresh": {
"title": "$:/core/ui/Buttons/refresh",
"tags": "$:/tags/PageControls",
"caption": "{{$:/core/images/refresh-button}} {{$:/language/Buttons/Refresh/Caption}}",
"description": "{{$:/language/Buttons/Refresh/Hint}}",
"text": "<$button message=\"tm-browser-refresh\" tooltip={{$:/language/Buttons/Refresh/Hint}} aria-label={{$:/language/Buttons/Refresh/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/refresh-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Refresh/Caption}}/></span>\n</$list>\n</$button>"
},
"$:/core/ui/Buttons/save-wiki": {
"title": "$:/core/ui/Buttons/save-wiki",
"tags": "$:/tags/PageControls",
"caption": "{{$:/core/images/save-button}} {{$:/language/Buttons/SaveWiki/Caption}}",
"description": "{{$:/language/Buttons/SaveWiki/Hint}}",
"text": "<$button tooltip={{$:/language/Buttons/SaveWiki/Hint}} aria-label={{$:/language/Buttons/SaveWiki/Caption}} class=<<tv-config-toolbar-class>>>\n<$wikify name=\"site-title\" text={{$:/config/SaveWikiButton/Filename}}>\n<$action-sendmessage $message=\"tm-save-wiki\" $param={{$:/config/SaveWikiButton/Template}} filename=<<site-title>>/>\n</$wikify>\n<span class=\"tc-dirty-indicator\">\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/save-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/SaveWiki/Caption}}/></span>\n</$list>\n</span>\n</$button>"
},
"$:/core/ui/Buttons/storyview": {
"title": "$:/core/ui/Buttons/storyview",
"tags": "$:/tags/PageControls",
"caption": "{{$:/core/images/storyview-classic}} {{$:/language/Buttons/StoryView/Caption}}",
"description": "{{$:/language/Buttons/StoryView/Hint}}",
"text": "\\define icon()\n$:/core/images/storyview-$(storyview)$\n\\end\n<span class=\"tc-popup-keep\">\n<$button popup=<<qualify \"$:/state/popup/storyview\">> tooltip={{$:/language/Buttons/StoryView/Hint}} aria-label={{$:/language/Buttons/StoryView/Caption}} class=<<tv-config-toolbar-class>> selectedClass=\"tc-selected\">\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n<$set name=\"storyview\" value={{$:/view}}>\n<$transclude tiddler=<<icon>>/>\n</$set>\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/StoryView/Caption}}/></span>\n</$list>\n</$button>\n</span>\n<$reveal state=<<qualify \"$:/state/popup/storyview\">> type=\"popup\" position=\"below\" animate=\"yes\">\n<div class=\"tc-drop-down\">\n{{$:/snippets/viewswitcher}}\n</div>\n</$reveal>"
},
"$:/core/ui/Buttons/tag-manager": {
"title": "$:/core/ui/Buttons/tag-manager",
"tags": "$:/tags/PageControls",
"caption": "{{$:/core/images/tag-button}} {{$:/language/Buttons/TagManager/Caption}}",
"description": "{{$:/language/Buttons/TagManager/Hint}}",
"text": "\\define control-panel-button(class)\n<$button to=\"$:/TagManager\" tooltip={{$:/language/Buttons/TagManager/Hint}} aria-label={{$:/language/Buttons/TagManager/Caption}} class=\"\"\"$(tv-config-toolbar-class)$ $class$\"\"\">\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/tag-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/TagManager/Caption}}/></span>\n</$list>\n</$button>\n\\end\n\n<$list filter=\"[list[$:/StoryList]] +[field:title[$:/TagManager]]\" emptyMessage=<<control-panel-button>>>\n<<control-panel-button \"tc-selected\">>\n</$list>\n"
},
"$:/core/ui/Buttons/theme": {
"title": "$:/core/ui/Buttons/theme",
"tags": "$:/tags/PageControls",
"caption": "{{$:/core/images/theme-button}} {{$:/language/Buttons/Theme/Caption}}",
"description": "{{$:/language/Buttons/Theme/Hint}}",
"text": "<span class=\"tc-popup-keep\">\n<$button popup=<<qualify \"$:/state/popup/theme\">> tooltip={{$:/language/Buttons/Theme/Hint}} aria-label={{$:/language/Buttons/Theme/Caption}} class=<<tv-config-toolbar-class>> selectedClass=\"tc-selected\">\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/theme-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Theme/Caption}}/></span>\n</$list>\n</$button>\n</span>\n<$reveal state=<<qualify \"$:/state/popup/theme\">> type=\"popup\" position=\"below\" animate=\"yes\">\n<div class=\"tc-drop-down\">\n<$linkcatcher to=\"$:/theme\">\n{{$:/snippets/themeswitcher}}\n</$linkcatcher>\n</div>\n</$reveal>"
},
"$:/core/ui/Buttons/timestamp": {
"title": "$:/core/ui/Buttons/timestamp",
"tags": "$:/tags/PageControls",
"caption": "{{$:/core/images/timestamp-on}} {{$:/language/Buttons/Timestamp/Caption}}",
"description": "{{$:/language/Buttons/Timestamp/Hint}}",
"text": "<$reveal type=\"nomatch\" state=\"$:/config/TimestampDisable\" text=\"yes\">\n<$button tooltip={{$:/language/Buttons/Timestamp/On/Hint}} aria-label={{$:/language/Buttons/Timestamp/On/Caption}} class=<<tv-config-toolbar-class>>>\n<$action-setfield $tiddler=\"$:/config/TimestampDisable\" $value=\"yes\"/>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/timestamp-on}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Timestamp/On/Caption}}/></span>\n</$list>\n</$button>\n</$reveal>\n<$reveal type=\"match\" state=\"$:/config/TimestampDisable\" text=\"yes\">\n<$button tooltip={{$:/language/Buttons/Timestamp/Off/Hint}} aria-label={{$:/language/Buttons/Timestamp/Off/Caption}} class=<<tv-config-toolbar-class>>>\n<$action-setfield $tiddler=\"$:/config/TimestampDisable\" $value=\"no\"/>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/timestamp-off}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Timestamp/Off/Caption}}/></span>\n</$list>\n</$button>\n</$reveal>"
},
"$:/core/ui/Buttons/unfold-all": {
"title": "$:/core/ui/Buttons/unfold-all",
"tags": "$:/tags/PageControls",
"caption": "{{$:/core/images/unfold-all-button}} {{$:/language/Buttons/UnfoldAll/Caption}}",
"description": "{{$:/language/Buttons/UnfoldAll/Hint}}",
"text": "<$button tooltip={{$:/language/Buttons/UnfoldAll/Hint}} aria-label={{$:/language/Buttons/UnfoldAll/Caption}} class=<<tv-config-toolbar-class>>>\n<$action-sendmessage $message=\"tm-unfold-all-tiddlers\" $param=<<currentTiddler>> foldedStatePrefix=\"$:/state/folded/\"/>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\" variable=\"listItem\">\n{{$:/core/images/unfold-all-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/UnfoldAll/Caption}}/></span>\n</$list>\n</$button>"
},
"$:/core/ui/PageTemplate/pagecontrols": {
"title": "$:/core/ui/PageTemplate/pagecontrols",
"text": "\\define config-title()\n$:/config/PageControlButtons/Visibility/$(listItem)$\n\\end\n<div class=\"tc-page-controls\">\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/PageControls]!has[draft.of]]\" variable=\"listItem\">\n<$reveal type=\"nomatch\" state=<<config-title>> text=\"hide\">\n<$set name=\"tv-config-toolbar-class\" filter=\"[<tv-config-toolbar-class>] [<listItem>encodeuricomponent[]addprefix[tc-btn-]]\">\n<$transclude tiddler=<<listItem>> mode=\"inline\"/>\n</$set>\n</$reveal>\n</$list>\n</div>\n\n"
},
"$:/core/ui/PageStylesheet": {
"title": "$:/core/ui/PageStylesheet",
"text": "\\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]\n\n<$set name=\"currentTiddler\" value={{$:/language}}>\n\n<$set name=\"languageTitle\" value={{!!name}}>\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/Stylesheet]!has[draft.of]]\">\n<$transclude mode=\"block\"/>\n</$list>\n\n</$set>\n\n</$set>\n"
},
"$:/core/ui/PageTemplate/alerts": {
"title": "$:/core/ui/PageTemplate/alerts",
"tags": "$:/tags/PageTemplate",
"text": "<div class=\"tc-alerts\">\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/Alert]!has[draft.of]]\" template=\"$:/core/ui/AlertTemplate\" storyview=\"pop\"/>\n\n</div>\n"
},
"$:/core/ui/PageTemplate/drafts": {
"title": "$:/core/ui/PageTemplate/drafts",
"tags": "$:/tags/PageTemplate",
"text": "\\whitespace trim\n<$reveal state=\"$:/status/IsReadOnly\" type=\"nomatch\" text=\"yes\" tag=\"div\" class=\"tc-drafts-list\">\n<$list filter=\"[has[draft.of]!sort[modified]] -[list[$:/StoryList]]\">\n<$link>\n{{$:/core/images/edit-button}} <$text text=<<currentTiddler>>/>\n</$link>\n</$list>\n</$reveal>\n"
},
"$:/core/ui/PageTemplate/pluginreloadwarning": {
"title": "$:/core/ui/PageTemplate/pluginreloadwarning",
"tags": "$:/tags/PageTemplate",
"text": "\\define lingo-base() $:/language/\n\n<$list filter=\"[has[plugin-type]haschanged[]!plugin-type[import]limit[1]]\">\n\n<$reveal type=\"nomatch\" state=\"$:/temp/HidePluginWarning\" text=\"yes\">\n\n<div class=\"tc-plugin-reload-warning\">\n\n<$set name=\"tv-config-toolbar-class\" value=\"\">\n\n<<lingo PluginReloadWarning>> <$button set=\"$:/temp/HidePluginWarning\" setTo=\"yes\" class=\"tc-btn-invisible\">{{$:/core/images/close-button}}</$button>\n\n</$set>\n\n</div>\n\n</$reveal>\n\n</$list>\n"
},
"$:/core/ui/PageTemplate/sidebar": {
"title": "$:/core/ui/PageTemplate/sidebar",
"tags": "$:/tags/PageTemplate",
"text": "\\define config-title()\n$:/config/SideBarSegments/Visibility/$(listItem)$\n\\end\n\n<$scrollable fallthrough=\"no\" class=\"tc-sidebar-scrollable\">\n\n<div class=\"tc-sidebar-header\">\n\n<$reveal state=\"$:/state/sidebar\" type=\"match\" text=\"yes\" default=\"yes\" retain=\"yes\" animate=\"yes\">\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/SideBarSegment]!has[draft.of]]\" variable=\"listItem\">\n\n<$reveal type=\"nomatch\" state=<<config-title>> text=\"hide\" tag=\"div\">\n\n<$transclude tiddler=<<listItem>> mode=\"block\"/>\n\n</$reveal>\n\n</$list>\n\n</$reveal>\n\n</div>\n\n</$scrollable>"
},
"$:/core/ui/PageTemplate/story": {
"title": "$:/core/ui/PageTemplate/story",
"tags": "$:/tags/PageTemplate",
"text": "<section class=\"tc-story-river\">\n\n<section class=\"story-backdrop\">\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/AboveStory]!has[draft.of]]\">\n\n<$transclude/>\n\n</$list>\n\n</section>\n\n<$list filter=\"[list[$:/StoryList]]\" history=\"$:/HistoryList\" template=\"$:/core/ui/ViewTemplate\" editTemplate=\"$:/core/ui/EditTemplate\" storyview={{$:/view}} emptyMessage={{$:/config/EmptyStoryMessage}}/>\n\n<section class=\"story-frontdrop\">\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/BelowStory]!has[draft.of]]\">\n\n<$transclude/>\n\n</$list>\n\n</section>\n\n</section>\n"
},
"$:/core/ui/PageTemplate/topleftbar": {
"title": "$:/core/ui/PageTemplate/topleftbar",
"tags": "$:/tags/PageTemplate",
"text": "<span class=\"tc-topbar tc-topbar-left\">\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/TopLeftBar]!has[draft.of]]\" variable=\"listItem\">\n\n<$transclude tiddler=<<listItem>> mode=\"inline\"/>\n\n</$list>\n\n</span>\n"
},
"$:/core/ui/PageTemplate/toprightbar": {
"title": "$:/core/ui/PageTemplate/toprightbar",
"tags": "$:/tags/PageTemplate",
"text": "<span class=\"tc-topbar tc-topbar-right\">\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/TopRightBar]!has[draft.of]]\" variable=\"listItem\">\n\n<$transclude tiddler=<<listItem>> mode=\"inline\"/>\n\n</$list>\n\n</span>\n"
},
"$:/core/ui/PageTemplate": {
"title": "$:/core/ui/PageTemplate",
"text": "\\define containerClasses()\ntc-page-container tc-page-view-$(storyviewTitle)$ tc-language-$(languageTitle)$\n\\end\n\\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]\n\n<$set name=\"tv-config-toolbar-icons\" value={{$:/config/Toolbar/Icons}}>\n\n<$set name=\"tv-config-toolbar-text\" value={{$:/config/Toolbar/Text}}>\n\n<$set name=\"tv-config-toolbar-class\" value={{$:/config/Toolbar/ButtonClass}}>\n\n<$set name=\"tv-show-missing-links\" value={{$:/config/MissingLinks}}>\n\n<$set name=\"storyviewTitle\" value={{$:/view}}>\n\n<$set name=\"currentTiddler\" value={{$:/language}}>\n\n<$set name=\"languageTitle\" value={{!!name}}>\n\n<$set name=\"currentTiddler\" value=\"\">\n\n<div class=<<containerClasses>>>\n\n<$navigator story=\"$:/StoryList\" history=\"$:/HistoryList\" openLinkFromInsideRiver={{$:/config/Navigation/openLinkFromInsideRiver}} openLinkFromOutsideRiver={{$:/config/Navigation/openLinkFromOutsideRiver}} relinkOnRename={{$:/config/RelinkOnRename}}>\n\n<$dropzone>\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/PageTemplate]!has[draft.of]]\" variable=\"listItem\">\n\n<$transclude tiddler=<<listItem>>/>\n\n</$list>\n\n</$dropzone>\n\n</$navigator>\n\n</div>\n\n</$set>\n\n</$set>\n\n</$set>\n\n</$set>\n\n</$set>\n\n</$set>\n\n</$set>\n\n</$set>\n"
},
"$:/core/ui/PluginInfo": {
"title": "$:/core/ui/PluginInfo",
"text": "\\define localised-info-tiddler-title()\n$(currentTiddler)$/$(languageTitle)$/$(currentTab)$\n\\end\n\\define info-tiddler-title()\n$(currentTiddler)$/$(currentTab)$\n\\end\n\\define default-tiddler-title()\n$:/core/ui/PluginInfo/Default/$(currentTab)$\n\\end\n<$transclude tiddler=<<localised-info-tiddler-title>> mode=\"block\">\n<$transclude tiddler=<<currentTiddler>> subtiddler=<<localised-info-tiddler-title>> mode=\"block\">\n<$transclude tiddler=<<currentTiddler>> subtiddler=<<info-tiddler-title>> mode=\"block\">\n<$transclude tiddler=<<default-tiddler-title>> mode=\"block\">\n{{$:/language/ControlPanel/Plugin/NoInfoFound/Hint}}\n</$transclude>\n</$transclude>\n</$transclude>\n</$transclude>\n"
},
"$:/core/ui/PluginInfo/Default/contents": {
"title": "$:/core/ui/PluginInfo/Default/contents",
"text": "\\define lingo-base() $:/language/TiddlerInfo/Advanced/PluginInfo/\n<<lingo Hint>>\n<ul>\n<$list filter=\"[all[current]plugintiddlers[]sort[title]]\" emptyMessage=<<lingo Empty/Hint>>>\n<li>\n<$link to={{!!title}}>\n<$view field=\"title\"/>\n</$link>\n</li>\n</$list>\n</ul>\n"
},
"$:/core/ui/PluginListItemTemplate": {
"title": "$:/core/ui/PluginListItemTemplate",
"text": "<div class=\"tc-menu-list-item\">\n<$link to={{!!title}}>\n<$view field=\"description\">\n<$view field=\"title\"/>\n</$view>\n</$link>\n</div>"
},
"$:/core/ui/SearchResults": {
"title": "$:/core/ui/SearchResults",
"text": "<div class=\"tc-search-results\">\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/SearchResults]!has[draft.of]butfirst[]limit[1]]\" emptyMessage=\"\"\"\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/SearchResults]!has[draft.of]]\">\n<$transclude mode=\"block\"/>\n</$list>\n\"\"\">\n\n<$macrocall $name=\"tabs\" tabsList=\"[all[shadows+tiddlers]tag[$:/tags/SearchResults]!has[draft.of]]\" default={{$:/config/SearchResults/Default}}/>\n\n</$list>\n\n</div>\n"
},
"$:/core/ui/SideBar/More": {
"title": "$:/core/ui/SideBar/More",
"tags": "$:/tags/SideBar",
"caption": "{{$:/language/SideBar/More/Caption}}",
"text": "<div class=\"tc-more-sidebar\">\n<$macrocall $name=\"tabs\" tabsList=\"[all[shadows+tiddlers]tag[$:/tags/MoreSideBar]!has[draft.of]]\" default={{$:/config/DefaultMoreSidebarTab}} state=\"$:/state/tab/moresidebar\" class=\"tc-vertical\" />\n</div>"
},
"$:/core/ui/SideBar/Open": {
"title": "$:/core/ui/SideBar/Open",
"tags": "$:/tags/SideBar",
"caption": "{{$:/language/SideBar/Open/Caption}}",
"text": "\\whitespace trim\n\\define lingo-base() $:/language/CloseAll/\n\n\\define drop-actions()\n<$action-listops $tiddler=\"$:/StoryList\" $subfilter=\"+[insertbefore:currentTiddler<actionTiddler>]\"/>\n\\end\n\n<$list filter=\"[list[$:/StoryList]]\" history=\"$:/HistoryList\" storyview=\"pop\">\n<div style=\"position: relative;\">\n<$droppable actions=<<drop-actions>>>\n<div class=\"tc-droppable-placeholder\">\n \n</div>\n<div>\n<$button message=\"tm-close-tiddler\" tooltip={{$:/language/Buttons/Close/Hint}} aria-label={{$:/language/Buttons/Close/Caption}} class=\"tc-btn-invisible tc-btn-mini\">×</$button> <$link to={{!!title}}><$view field=\"title\"/></$link>\n</div>\n</$droppable>\n</div>\n</$list>\n<$tiddler tiddler=\"\">\n<$droppable actions=<<drop-actions>>>\n<div class=\"tc-droppable-placeholder\">\n \n</div>\n<$button message=\"tm-close-all-tiddlers\" class=\"tc-btn-invisible tc-btn-mini\"><<lingo Button>></$button>\n</$droppable>\n</$tiddler>\n"
},
"$:/core/ui/SideBar/Recent": {
"title": "$:/core/ui/SideBar/Recent",
"tags": "$:/tags/SideBar",
"caption": "{{$:/language/SideBar/Recent/Caption}}",
"text": "<$macrocall $name=\"timeline\" format={{$:/language/RecentChanges/DateFormat}}/>\n"
},
"$:/core/ui/SideBar/Tools": {
"title": "$:/core/ui/SideBar/Tools",
"tags": "$:/tags/SideBar",
"caption": "{{$:/language/SideBar/Tools/Caption}}",
"text": "\\define lingo-base() $:/language/ControlPanel/\n\\define config-title()\n$:/config/PageControlButtons/Visibility/$(listItem)$\n\\end\n\n<<lingo Basics/Version/Prompt>> <<version>>\n\n<$set name=\"tv-config-toolbar-icons\" value=\"yes\">\n\n<$set name=\"tv-config-toolbar-text\" value=\"yes\">\n\n<$set name=\"tv-config-toolbar-class\" value=\"\">\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/PageControls]!has[draft.of]]\" variable=\"listItem\">\n\n<div style=\"position:relative;\" class={{{ [<listItem>encodeuricomponent[]addprefix[tc-btn-]] }}}>\n\n<$checkbox tiddler=<<config-title>> field=\"text\" checked=\"show\" unchecked=\"hide\" default=\"show\"/> <$transclude tiddler=<<listItem>>/> <i class=\"tc-muted\"><$transclude tiddler=<<listItem>> field=\"description\"/></i>\n\n</div>\n\n</$list>\n\n</$set>\n\n</$set>\n\n</$set>\n"
},
"$:/core/ui/SideBarLists": {
"title": "$:/core/ui/SideBarLists",
"text": "<$transclude tiddler=\"$:/core/ui/SideBarSegments/search\"/>\n\n<$transclude tiddler=\"$:/core/ui/SideBarSegments/tabs\"/>\n\n"
},
"$:/core/ui/SideBarSegments/page-controls": {
"title": "$:/core/ui/SideBarSegments/page-controls",
"tags": "$:/tags/SideBarSegment",
"text": "{{||$:/core/ui/PageTemplate/pagecontrols}}\n"
},
"$:/core/ui/SideBarSegments/search": {
"title": "$:/core/ui/SideBarSegments/search",
"tags": "$:/tags/SideBarSegment",
"text": "<div class=\"tc-sidebar-lists\">\n\n<$set name=\"searchTiddler\" value=\"$:/temp/search\">\n<div class=\"tc-search\">\n<$edit-text tiddler=\"$:/temp/search\" type=\"search\" tag=\"input\" focus={{$:/config/Search/AutoFocus}} focusPopup=<<qualify \"$:/state/popup/search-dropdown\">> class=\"tc-popup-handle\"/>\n<$reveal state=\"$:/temp/search\" type=\"nomatch\" text=\"\">\n<$button tooltip={{$:/language/Buttons/AdvancedSearch/Hint}} aria-label={{$:/language/Buttons/AdvancedSearch/Caption}} class=\"tc-btn-invisible\">\n<$action-setfield $tiddler=\"$:/temp/advancedsearch\" text={{$:/temp/search}}/>\n<$action-setfield $tiddler=\"$:/temp/search\" text=\"\"/>\n<$action-navigate $to=\"$:/AdvancedSearch\"/>\n{{$:/core/images/advanced-search-button}}\n</$button>\n<$button class=\"tc-btn-invisible\">\n<$action-setfield $tiddler=\"$:/temp/search\" text=\"\" />\n{{$:/core/images/close-button}}\n</$button>\n<$button popup=<<qualify \"$:/state/popup/search-dropdown\">> class=\"tc-btn-invisible\">\n{{$:/core/images/down-arrow}}\n<$list filter=\"[{$:/temp/search}minlength{$:/config/Search/MinLength}limit[1]]\" variable=\"listItem\">\n<$set name=\"searchTerm\" value={{{ [<searchTiddler>get[text]] }}}>\n<$set name=\"resultCount\" value=\"\"\"<$count filter=\"[!is[system]search<searchTerm>]\"/>\"\"\">\n{{$:/language/Search/Matches}}\n</$set>\n</$set>\n</$list>\n</$button>\n</$reveal>\n<$reveal state=\"$:/temp/search\" type=\"match\" text=\"\">\n<$button to=\"$:/AdvancedSearch\" tooltip={{$:/language/Buttons/AdvancedSearch/Hint}} aria-label={{$:/language/Buttons/AdvancedSearch/Caption}} class=\"tc-btn-invisible\">\n{{$:/core/images/advanced-search-button}}\n</$button>\n</$reveal>\n</div>\n\n<$reveal tag=\"div\" class=\"tc-block-dropdown-wrapper\" state=\"$:/temp/search\" type=\"nomatch\" text=\"\">\n\n<$reveal tag=\"div\" class=\"tc-block-dropdown tc-search-drop-down tc-popup-handle\" state=<<qualify \"$:/state/popup/search-dropdown\">> type=\"nomatch\" text=\"\" default=\"\">\n\n<$list filter=\"[{$:/temp/search}minlength{$:/config/Search/MinLength}limit[1]]\" emptyMessage=\"\"\"<div class=\"tc-search-results\">{{$:/language/Search/Search/TooShort}}</div>\"\"\" variable=\"listItem\">\n\n{{$:/core/ui/SearchResults}}\n\n</$list>\n\n</$reveal>\n\n</$reveal>\n\n</$set>\n\n</div>\n"
},
"$:/core/ui/SideBarSegments/site-subtitle": {
"title": "$:/core/ui/SideBarSegments/site-subtitle",
"tags": "$:/tags/SideBarSegment",
"text": "<div class=\"tc-site-subtitle\">\n\n<$transclude tiddler=\"$:/SiteSubtitle\" mode=\"inline\"/>\n\n</div>\n"
},
"$:/core/ui/SideBarSegments/site-title": {
"title": "$:/core/ui/SideBarSegments/site-title",
"tags": "$:/tags/SideBarSegment",
"text": "<h1 class=\"tc-site-title\">\n\n<$transclude tiddler=\"$:/SiteTitle\" mode=\"inline\"/>\n\n</h1>\n"
},
"$:/core/ui/SideBarSegments/tabs": {
"title": "$:/core/ui/SideBarSegments/tabs",
"tags": "$:/tags/SideBarSegment",
"text": "<div class=\"tc-sidebar-lists\">\n\n<$macrocall $name=\"tabs\" tabsList=\"[all[shadows+tiddlers]tag[$:/tags/SideBar]!has[draft.of]]\" default={{$:/config/DefaultSidebarTab}} state=\"$:/state/tab/sidebar\" />\n\n</div>\n"
},
"$:/TagManager": {
"title": "$:/TagManager",
"icon": "$:/core/images/tag-button",
"color": "#bbb",
"caption": "{{$:/language/TagManager/Caption}}",
"text": "\\define lingo-base() $:/language/TagManager/\n\\define iconEditorTab(type)\n<$list filter=\"[all[shadows+tiddlers]is[image]] [all[shadows+tiddlers]tag[$:/tags/Image]] -[type[application/pdf]] +[sort[title]] +[$type$is[system]]\">\n<$link to={{!!title}}>\n<$transclude/> <$view field=\"title\"/>\n</$link>\n</$list>\n\\end\n\\define iconEditor(title)\n<div class=\"tc-drop-down-wrapper\">\n<$button popupTitle={{{ [[$:/state/popup/icon/]addsuffix<__title__>] }}} class=\"tc-btn-invisible tc-btn-dropdown\">{{$:/core/images/down-arrow}}</$button>\n<$reveal stateTitle={{{ [[$:/state/popup/icon/]addsuffix<__title__>] }}} type=\"popup\" position=\"belowleft\" text=\"\" default=\"\">\n<div class=\"tc-drop-down\">\n<$linkcatcher actions=\"\"\"<$action-setfield $tiddler=<<__title__>> icon=<<navigateTo>>/>\"\"\">\n<<iconEditorTab type:\"!\">>\n<hr/>\n<<iconEditorTab type:\"\">>\n</$linkcatcher>\n</div>\n</$reveal>\n</div>\n\\end\n\\define toggleButton(state)\n<$reveal stateTitle=<<__state__>> type=\"match\" text=\"closed\" default=\"closed\">\n<$button setTitle=<<__state__>> setTo=\"open\" class=\"tc-btn-invisible tc-btn-dropdown\" selectedClass=\"tc-selected\">\n{{$:/core/images/info-button}}\n</$button>\n</$reveal>\n<$reveal stateTitle=<<__state__>> type=\"match\" text=\"open\" default=\"closed\">\n<$button setTitle=<<__state__>> setTo=\"closed\" class=\"tc-btn-invisible tc-btn-dropdown\" selectedClass=\"tc-selected\">\n{{$:/core/images/info-button}}\n</$button>\n</$reveal>\n\\end\n<table class=\"tc-tag-manager-table\">\n<tbody>\n<tr>\n<th><<lingo Colour/Heading>></th>\n<th class=\"tc-tag-manager-tag\"><<lingo Tag/Heading>></th>\n<th><<lingo Count/Heading>></th>\n<th><<lingo Icon/Heading>></th>\n<th><<lingo Info/Heading>></th>\n</tr>\n<$list filter=\"[tags[]!is[system]sort[title]]\">\n<tr>\n<td><$edit-text field=\"color\" tag=\"input\" type=\"color\"/></td>\n<td>{{||$:/core/ui/TagTemplate}}</td>\n<td><$count filter=\"[all[current]tagging[]]\"/></td>\n<td>\n<$macrocall $name=\"iconEditor\" title={{!!title}}/>\n</td>\n<td>\n<$macrocall $name=\"toggleButton\" state={{{ [[$:/state/tag-manager/]addsuffix<currentTiddler>] }}} /> \n</td>\n</tr>\n<tr>\n<td></td>\n<td colspan=\"4\">\n<$reveal stateTitle={{{ [[$:/state/tag-manager/]addsuffix<currentTiddler>] }}} type=\"match\" text=\"open\" default=\"\">\n<table>\n<tbody>\n<tr><td><<lingo Colour/Heading>></td><td><$edit-text field=\"color\" tag=\"input\" type=\"text\" size=\"9\"/></td></tr>\n<tr><td><<lingo Icon/Heading>></td><td><$edit-text field=\"icon\" tag=\"input\" size=\"45\"/></td></tr>\n</tbody>\n</table>\n</$reveal>\n</td>\n</tr>\n</$list>\n<tr>\n<td></td>\n<td style=\"position:relative;\">\n{{$:/core/ui/UntaggedTemplate}}\n</td>\n<td>\n<small class=\"tc-menu-list-count\"><$count filter=\"[untagged[]!is[system]] -[tags[]]\"/></small>\n</td>\n<td></td>\n<td></td>\n</tr>\n</tbody>\n</table>\n"
},
"$:/core/ui/TagTemplate": {
"title": "$:/core/ui/TagTemplate",
"text": "\\whitespace trim\n<span class=\"tc-tag-list-item\">\n<$set name=\"transclusion\" value=<<currentTiddler>>>\n<$macrocall $name=\"tag-pill-body\" tag=<<currentTiddler>> icon={{!!icon}} colour={{!!color}} palette={{$:/palette}} element-tag=\"\"\"$button\"\"\" element-attributes=\"\"\"popup=<<qualify \"$:/state/popup/tag\">> dragFilter='[all[current]tagging[]]' tag='span'\"\"\"/>\n<$reveal state=<<qualify \"$:/state/popup/tag\">> type=\"popup\" position=\"below\" animate=\"yes\" class=\"tc-drop-down\">\n<$set name=\"tv-show-missing-links\" value=\"yes\">\n<$transclude tiddler=\"$:/core/ui/ListItemTemplate\"/>\n</$set>\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/TagDropdown]!has[draft.of]]\" variable=\"listItem\"> \n<$transclude tiddler=<<listItem>>/> \n</$list>\n<hr>\n<$macrocall $name=\"list-tagged-draggable\" tag=<<currentTiddler>>/>\n</$reveal>\n</$set>\n</span>\n"
},
"$:/core/ui/TiddlerFieldTemplate": {
"title": "$:/core/ui/TiddlerFieldTemplate",
"text": "<tr class=\"tc-view-field\">\n<td class=\"tc-view-field-name\">\n<$text text=<<listItem>>/>\n</td>\n<td class=\"tc-view-field-value\">\n<$view field=<<listItem>>/>\n</td>\n</tr>"
},
"$:/core/ui/TiddlerFields": {
"title": "$:/core/ui/TiddlerFields",
"text": "<table class=\"tc-view-field-table\">\n<tbody>\n<$list filter=\"[all[current]fields[]sort[title]] -text\" template=\"$:/core/ui/TiddlerFieldTemplate\" variable=\"listItem\"/>\n</tbody>\n</table>\n"
},
"$:/core/ui/TiddlerInfo/Advanced/PluginInfo": {
"title": "$:/core/ui/TiddlerInfo/Advanced/PluginInfo",
"tags": "$:/tags/TiddlerInfo/Advanced",
"text": "\\define lingo-base() $:/language/TiddlerInfo/Advanced/PluginInfo/\n<$list filter=\"[all[current]has[plugin-type]]\">\n\n! <<lingo Heading>>\n\n<<lingo Hint>>\n<ul>\n<$list filter=\"[all[current]plugintiddlers[]sort[title]]\" emptyMessage=<<lingo Empty/Hint>>>\n<li>\n<$link to={{!!title}}>\n<$view field=\"title\"/>\n</$link>\n</li>\n</$list>\n</ul>\n\n</$list>\n"
},
"$:/core/ui/TiddlerInfo/Advanced/ShadowInfo": {
"title": "$:/core/ui/TiddlerInfo/Advanced/ShadowInfo",
"tags": "$:/tags/TiddlerInfo/Advanced",
"text": "\\define lingo-base() $:/language/TiddlerInfo/Advanced/ShadowInfo/\n<$set name=\"infoTiddler\" value=<<currentTiddler>>>\n\n''<<lingo Heading>>''\n\n<$list filter=\"[all[current]!is[shadow]]\">\n\n<<lingo NotShadow/Hint>>\n\n</$list>\n\n<$list filter=\"[all[current]is[shadow]]\">\n\n<<lingo Shadow/Hint>>\n\n<$list filter=\"[all[current]shadowsource[]]\">\n\n<$set name=\"pluginTiddler\" value=<<currentTiddler>>>\n<<lingo Shadow/Source>>\n</$set>\n\n</$list>\n\n<$list filter=\"[all[current]is[shadow]is[tiddler]]\">\n\n<<lingo OverriddenShadow/Hint>>\n\n</$list>\n\n\n</$list>\n</$set>\n"
},
"$:/core/ui/TiddlerInfo/Advanced": {
"title": "$:/core/ui/TiddlerInfo/Advanced",
"tags": "$:/tags/TiddlerInfo",
"caption": "{{$:/language/TiddlerInfo/Advanced/Caption}}",
"text": "<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/TiddlerInfo/Advanced]!has[draft.of]]\" variable=\"listItem\">\n<$transclude tiddler=<<listItem>>/>\n\n</$list>\n"
},
"$:/core/ui/TiddlerInfo/Fields": {
"title": "$:/core/ui/TiddlerInfo/Fields",
"tags": "$:/tags/TiddlerInfo",
"caption": "{{$:/language/TiddlerInfo/Fields/Caption}}",
"text": "<$transclude tiddler=\"$:/core/ui/TiddlerFields\"/>\n"
},
"$:/core/ui/TiddlerInfo/List": {
"title": "$:/core/ui/TiddlerInfo/List",
"tags": "$:/tags/TiddlerInfo",
"caption": "{{$:/language/TiddlerInfo/List/Caption}}",
"text": "\\define lingo-base() $:/language/TiddlerInfo/\n<$list filter=\"[list{!!title}]\" emptyMessage=<<lingo List/Empty>> template=\"$:/core/ui/ListItemTemplate\"/>\n"
},
"$:/core/ui/TiddlerInfo/Listed": {
"title": "$:/core/ui/TiddlerInfo/Listed",
"tags": "$:/tags/TiddlerInfo",
"caption": "{{$:/language/TiddlerInfo/Listed/Caption}}",
"text": "\\define lingo-base() $:/language/TiddlerInfo/\n<$list filter=\"[all[current]listed[]!is[system]]\" emptyMessage=<<lingo Listed/Empty>> template=\"$:/core/ui/ListItemTemplate\"/>\n"
},
"$:/core/ui/TiddlerInfo/References": {
"title": "$:/core/ui/TiddlerInfo/References",
"tags": "$:/tags/TiddlerInfo",
"caption": "{{$:/language/TiddlerInfo/References/Caption}}",
"text": "\\define lingo-base() $:/language/TiddlerInfo/\n<$list filter=\"[all[current]backlinks[]sort[title]]\" emptyMessage=<<lingo References/Empty>> template=\"$:/core/ui/ListItemTemplate\">\n</$list>"
},
"$:/core/ui/TiddlerInfo/Tagging": {
"title": "$:/core/ui/TiddlerInfo/Tagging",
"tags": "$:/tags/TiddlerInfo",
"caption": "{{$:/language/TiddlerInfo/Tagging/Caption}}",
"text": "\\define lingo-base() $:/language/TiddlerInfo/\n<$list filter=\"[all[current]tagging[]]\" emptyMessage=<<lingo Tagging/Empty>> template=\"$:/core/ui/ListItemTemplate\"/>\n"
},
"$:/core/ui/TiddlerInfo/Tools": {
"title": "$:/core/ui/TiddlerInfo/Tools",
"tags": "$:/tags/TiddlerInfo",
"caption": "{{$:/language/TiddlerInfo/Tools/Caption}}",
"text": "\\define lingo-base() $:/language/TiddlerInfo/\n\\define config-title()\n$:/config/ViewToolbarButtons/Visibility/$(listItem)$\n\\end\n<$set name=\"tv-config-toolbar-icons\" value=\"yes\">\n\n<$set name=\"tv-config-toolbar-text\" value=\"yes\">\n\n<$set name=\"tv-config-toolbar-class\" value=\"\">\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/ViewToolbar]!has[draft.of]]\" variable=\"listItem\">\n\n<$checkbox tiddler=<<config-title>> field=\"text\" checked=\"show\" unchecked=\"hide\" default=\"show\"/> <$transclude tiddler=<<listItem>>/> <i class=\"tc-muted\"><$transclude tiddler=<<listItem>> field=\"description\"/></i>\n\n</$list>\n\n</$set>\n\n</$set>\n\n</$set>\n"
},
"$:/core/ui/TiddlerInfo": {
"title": "$:/core/ui/TiddlerInfo",
"text": "<div style=\"position:relative;\">\n<div class=\"tc-tiddler-controls\" style=\"position:absolute;right:0;\">\n<$reveal state=\"$:/config/TiddlerInfo/Mode\" type=\"match\" text=\"sticky\">\n<$button set=<<tiddlerInfoState>> setTo=\"\" tooltip={{$:/language/Buttons/Info/Hint}} aria-label={{$:/language/Buttons/Info/Caption}} class=\"tc-btn-invisible\">\n{{$:/core/images/close-button}}\n</$button>\n</$reveal>\n</div>\n</div>\n\n<$macrocall $name=\"tabs\" tabsList=\"[all[shadows+tiddlers]tag[$:/tags/TiddlerInfo]!has[draft.of]]\" default={{$:/config/TiddlerInfo/Default}}/>"
},
"$:/core/ui/TopBar/menu": {
"title": "$:/core/ui/TopBar/menu",
"tags": "$:/tags/TopRightBar",
"text": "<$reveal state=\"$:/state/sidebar\" type=\"nomatch\" text=\"no\">\n<$button set=\"$:/state/sidebar\" setTo=\"no\" tooltip={{$:/language/Buttons/HideSideBar/Hint}} aria-label={{$:/language/Buttons/HideSideBar/Caption}} class=\"tc-btn-invisible\">{{$:/core/images/chevron-right}}</$button>\n</$reveal>\n<$reveal state=\"$:/state/sidebar\" type=\"match\" text=\"no\">\n<$button set=\"$:/state/sidebar\" setTo=\"yes\" tooltip={{$:/language/Buttons/ShowSideBar/Hint}} aria-label={{$:/language/Buttons/ShowSideBar/Caption}} class=\"tc-btn-invisible\">{{$:/core/images/chevron-left}}</$button>\n</$reveal>\n"
},
"$:/core/ui/UntaggedTemplate": {
"title": "$:/core/ui/UntaggedTemplate",
"text": "\\define lingo-base() $:/language/SideBar/\n<$button popup=<<qualify \"$:/state/popup/tag\">> class=\"tc-btn-invisible tc-untagged-label tc-tag-label\">\n<<lingo Tags/Untagged/Caption>>\n</$button>\n<$reveal state=<<qualify \"$:/state/popup/tag\">> type=\"popup\" position=\"below\">\n<div class=\"tc-drop-down\">\n<$list filter=\"[untagged[]!is[system]] -[tags[]] +[sort[title]]\" template=\"$:/core/ui/ListItemTemplate\"/>\n</div>\n</$reveal>\n"
},
"$:/core/ui/ViewTemplate/body": {
"title": "$:/core/ui/ViewTemplate/body",
"tags": "$:/tags/ViewTemplate",
"text": "<$reveal tag=\"div\" class=\"tc-tiddler-body\" type=\"nomatch\" stateTitle=<<folded-state>> text=\"hide\" retain=\"yes\" animate=\"yes\">\n\n<$list filter=\"[all[current]!has[plugin-type]!field:hide-body[yes]]\">\n\n<$transclude>\n\n<$transclude tiddler=\"$:/language/MissingTiddler/Hint\"/>\n\n</$transclude>\n\n</$list>\n\n</$reveal>\n"
},
"$:/core/ui/ViewTemplate/classic": {
"title": "$:/core/ui/ViewTemplate/classic",
"tags": "$:/tags/ViewTemplate $:/tags/EditTemplate",
"text": "\\define lingo-base() $:/language/ClassicWarning/\n<$list filter=\"[all[current]type[text/x-tiddlywiki]]\">\n<div class=\"tc-message-box\">\n\n<<lingo Hint>>\n\n<$button set=\"!!type\" setTo=\"text/vnd.tiddlywiki\"><<lingo Upgrade/Caption>></$button>\n\n</div>\n</$list>\n"
},
"$:/core/ui/ViewTemplate/import": {
"title": "$:/core/ui/ViewTemplate/import",
"tags": "$:/tags/ViewTemplate",
"text": "\\define lingo-base() $:/language/Import/\n\n\\define buttons()\n<$button message=\"tm-delete-tiddler\" param=<<currentTiddler>>><<lingo Listing/Cancel/Caption>></$button>\n<$button message=\"tm-perform-import\" param=<<currentTiddler>>><<lingo Listing/Import/Caption>></$button>\n<<lingo Listing/Preview>> <$select tiddler=\"$:/state/importpreviewtype\" default=\"$:/core/ui/ImportPreviews/Text\">\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/ImportPreview]!has[draft.of]]\">\n<option value=<<currentTiddler>>>{{!!caption}}</option>\n</$list>\n</$select>\n\\end\n\n<$list filter=\"[all[current]field:plugin-type[import]]\">\n\n<div class=\"tc-import\">\n\n<<lingo Listing/Hint>>\n\n<<buttons>>\n\n{{||$:/core/ui/ImportListing}}\n\n<<buttons>>\n\n</div>\n\n</$list>\n"
},
"$:/core/ui/ViewTemplate/plugin": {
"title": "$:/core/ui/ViewTemplate/plugin",
"tags": "$:/tags/ViewTemplate",
"text": "<$list filter=\"[all[current]has[plugin-type]] -[all[current]field:plugin-type[import]]\">\n<$set name=\"plugin-type\" value={{!!plugin-type}}>\n<$set name=\"default-popup-state\" value=\"yes\">\n<$set name=\"qualified-state\" value=<<qualify \"$:/state/plugin-info\">>>\n{{||$:/core/ui/Components/plugin-info}}\n</$set>\n</$set>\n</$set>\n</$list>\n"
},
"$:/core/ui/ViewTemplate/subtitle": {
"title": "$:/core/ui/ViewTemplate/subtitle",
"tags": "$:/tags/ViewTemplate",
"text": "<$reveal type=\"nomatch\" stateTitle=<<folded-state>> text=\"hide\" tag=\"div\" retain=\"yes\" animate=\"yes\">\n<div class=\"tc-subtitle\">\n<$link to={{!!modifier}}>\n<$view field=\"modifier\"/>\n</$link> <$view field=\"modified\" format=\"date\" template={{$:/language/Tiddler/DateFormat}}/>\n</div>\n</$reveal>\n"
},
"$:/core/ui/ViewTemplate/tags": {
"title": "$:/core/ui/ViewTemplate/tags",
"tags": "$:/tags/ViewTemplate",
"text": "<$reveal type=\"nomatch\" stateTitle=<<folded-state>> text=\"hide\" tag=\"div\" retain=\"yes\" animate=\"yes\">\n<div class=\"tc-tags-wrapper\"><$list filter=\"[all[current]tags[]sort[title]]\" template=\"$:/core/ui/TagTemplate\" storyview=\"pop\"/></div>\n</$reveal>\n"
},
"$:/core/ui/ViewTemplate/title": {
"title": "$:/core/ui/ViewTemplate/title",
"tags": "$:/tags/ViewTemplate",
"text": "\\define title-styles()\nfill:$(foregroundColor)$;\n\\end\n\\define config-title()\n$:/config/ViewToolbarButtons/Visibility/$(listItem)$\n\\end\n<div class=\"tc-tiddler-title\">\n<div class=\"tc-titlebar\">\n<span class=\"tc-tiddler-controls\">\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/ViewToolbar]!has[draft.of]]\" variable=\"listItem\"><$reveal type=\"nomatch\" state=<<config-title>> text=\"hide\"><$set name=\"tv-config-toolbar-class\" filter=\"[<tv-config-toolbar-class>] [<listItem>encodeuricomponent[]addprefix[tc-btn-]]\"><$transclude tiddler=<<listItem>>/></$set></$reveal></$list>\n</span>\n<$set name=\"tv-wikilinks\" value={{$:/config/Tiddlers/TitleLinks}}>\n<$link>\n<$set name=\"foregroundColor\" value={{!!color}}>\n<span class=\"tc-tiddler-title-icon\" style=<<title-styles>>>\n<$transclude tiddler={{!!icon}}/>\n</span>\n</$set>\n<$list filter=\"[all[current]removeprefix[$:/]]\">\n<h2 class=\"tc-title\" title={{$:/language/SystemTiddler/Tooltip}}>\n<span class=\"tc-system-title-prefix\">$:/</span><$text text=<<currentTiddler>>/>\n</h2>\n</$list>\n<$list filter=\"[all[current]!prefix[$:/]]\">\n<h2 class=\"tc-title\">\n<$view field=\"title\"/>\n</h2>\n</$list>\n</$link>\n</$set>\n</div>\n\n<$reveal type=\"nomatch\" text=\"\" default=\"\" state=<<tiddlerInfoState>> class=\"tc-tiddler-info tc-popup-handle\" animate=\"yes\" retain=\"yes\">\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/TiddlerInfoSegment]!has[draft.of]] [[$:/core/ui/TiddlerInfo]]\" variable=\"listItem\"><$transclude tiddler=<<listItem>> mode=\"block\"/></$list>\n\n</$reveal>\n</div>"
},
"$:/core/ui/ViewTemplate/unfold": {
"title": "$:/core/ui/ViewTemplate/unfold",
"tags": "$:/tags/ViewTemplate",
"text": "<$reveal tag=\"div\" type=\"nomatch\" state=\"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/fold-bar\" text=\"hide\">\n<$reveal tag=\"div\" type=\"nomatch\" stateTitle=<<folded-state>> text=\"hide\" default=\"show\" retain=\"yes\" animate=\"yes\">\n<$button tooltip={{$:/language/Buttons/Fold/Hint}} aria-label={{$:/language/Buttons/Fold/Caption}} class=\"tc-fold-banner\">\n<$action-sendmessage $message=\"tm-fold-tiddler\" $param=<<currentTiddler>> foldedState=<<folded-state>>/>\n{{$:/core/images/chevron-up}}\n</$button>\n</$reveal>\n<$reveal tag=\"div\" type=\"nomatch\" stateTitle=<<folded-state>> text=\"show\" default=\"show\" retain=\"yes\" animate=\"yes\">\n<$button tooltip={{$:/language/Buttons/Unfold/Hint}} aria-label={{$:/language/Buttons/Unfold/Caption}} class=\"tc-unfold-banner\">\n<$action-sendmessage $message=\"tm-fold-tiddler\" $param=<<currentTiddler>> foldedState=<<folded-state>>/>\n{{$:/core/images/chevron-down}}\n</$button>\n</$reveal>\n</$reveal>\n"
},
"$:/core/ui/ViewTemplate": {
"title": "$:/core/ui/ViewTemplate",
"text": "\\define frame-classes()\ntc-tiddler-frame tc-tiddler-view-frame $(missingTiddlerClass)$ $(shadowTiddlerClass)$ $(systemTiddlerClass)$ $(tiddlerTagClasses)$ $(userClass)$\n\\end\n\\define folded-state()\n$:/state/folded/$(currentTiddler)$\n\\end\n<$vars storyTiddler=<<currentTiddler>> tiddlerInfoState=<<qualify \"$:/state/popup/tiddler-info\">> userClass={{!!class}}><$tiddler tiddler=<<currentTiddler>>><div data-tiddler-title=<<currentTiddler>> data-tags={{!!tags}} class=<<frame-classes>>><$list filter=\"[all[shadows+tiddlers]tag[$:/tags/ViewTemplate]!has[draft.of]]\" variable=\"listItem\"><$transclude tiddler=<<listItem>>/></$list>\n</div>\n</$tiddler></$vars>\n"
},
"$:/core/ui/Buttons/clone": {
"title": "$:/core/ui/Buttons/clone",
"tags": "$:/tags/ViewToolbar",
"caption": "{{$:/core/images/clone-button}} {{$:/language/Buttons/Clone/Caption}}",
"description": "{{$:/language/Buttons/Clone/Hint}}",
"text": "\\whitespace trim\n<$button message=\"tm-new-tiddler\" param=<<currentTiddler>> tooltip={{$:/language/Buttons/Clone/Hint}} aria-label={{$:/language/Buttons/Clone/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/clone-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\">\n<$text text=\" \"/>\n<$text text={{$:/language/Buttons/Clone/Caption}}/>\n</span>\n</$list>\n</$button>"
},
"$:/core/ui/Buttons/close-others": {
"title": "$:/core/ui/Buttons/close-others",
"tags": "$:/tags/ViewToolbar",
"caption": "{{$:/core/images/close-others-button}} {{$:/language/Buttons/CloseOthers/Caption}}",
"description": "{{$:/language/Buttons/CloseOthers/Hint}}",
"text": "\\whitespace trim\n<$button message=\"tm-close-other-tiddlers\" param=<<currentTiddler>> tooltip={{$:/language/Buttons/CloseOthers/Hint}} aria-label={{$:/language/Buttons/CloseOthers/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/close-others-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\">\n<$text text=\" \"/>\n<$text text={{$:/language/Buttons/CloseOthers/Caption}}/>\n</span>\n</$list>\n</$button>"
},
"$:/core/ui/Buttons/close": {
"title": "$:/core/ui/Buttons/close",
"tags": "$:/tags/ViewToolbar",
"caption": "{{$:/core/images/close-button}} {{$:/language/Buttons/Close/Caption}}",
"description": "{{$:/language/Buttons/Close/Hint}}",
"text": "\\whitespace trim\n<$button message=\"tm-close-tiddler\" tooltip={{$:/language/Buttons/Close/Hint}} aria-label={{$:/language/Buttons/Close/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/close-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\">\n<$text text={{$:/language/Buttons/Close/Caption}}/>\n</span>\n</$list>\n</$button>"
},
"$:/core/ui/Buttons/edit": {
"title": "$:/core/ui/Buttons/edit",
"tags": "$:/tags/ViewToolbar",
"caption": "{{$:/core/images/edit-button}} {{$:/language/Buttons/Edit/Caption}}",
"description": "{{$:/language/Buttons/Edit/Hint}}",
"text": "\\whitespace trim\n<$button message=\"tm-edit-tiddler\" tooltip={{$:/language/Buttons/Edit/Hint}} aria-label={{$:/language/Buttons/Edit/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/edit-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\">\n<$text text=\" \"/>\n<$text text={{$:/language/Buttons/Edit/Caption}}/>\n</span>\n</$list>\n</$button>"
},
"$:/core/ui/Buttons/export-tiddler": {
"title": "$:/core/ui/Buttons/export-tiddler",
"tags": "$:/tags/ViewToolbar",
"caption": "{{$:/core/images/export-button}} {{$:/language/Buttons/ExportTiddler/Caption}}",
"description": "{{$:/language/Buttons/ExportTiddler/Hint}}",
"text": "\\define makeExportFilter()\n[[$(currentTiddler)$]]\n\\end\n<$macrocall $name=\"exportButton\" exportFilter=<<makeExportFilter>> lingoBase=\"$:/language/Buttons/ExportTiddler/\" baseFilename=<<currentTiddler>>/>"
},
"$:/core/ui/Buttons/fold-bar": {
"title": "$:/core/ui/Buttons/fold-bar",
"tags": "$:/tags/ViewToolbar",
"caption": "{{$:/core/images/chevron-up}} {{$:/language/Buttons/Fold/FoldBar/Caption}}",
"description": "{{$:/language/Buttons/Fold/FoldBar/Hint}}",
"text": "<!-- This dummy toolbar button is here to allow visibility of the fold-bar to be controlled as if it were a toolbar button -->"
},
"$:/core/ui/Buttons/fold-others": {
"title": "$:/core/ui/Buttons/fold-others",
"tags": "$:/tags/ViewToolbar",
"caption": "{{$:/core/images/fold-others-button}} {{$:/language/Buttons/FoldOthers/Caption}}",
"description": "{{$:/language/Buttons/FoldOthers/Hint}}",
"text": "\\whitespace trim\n<$button tooltip={{$:/language/Buttons/FoldOthers/Hint}} aria-label={{$:/language/Buttons/FoldOthers/Caption}} class=<<tv-config-toolbar-class>>>\n<$action-sendmessage $message=\"tm-fold-other-tiddlers\" $param=<<currentTiddler>> foldedStatePrefix=\"$:/state/folded/\"/>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\" variable=\"listItem\">\n{{$:/core/images/fold-others-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\">\n<$text text=\" \"/>\n<$text text={{$:/language/Buttons/FoldOthers/Caption}}/>\n</span>\n</$list>\n</$button>"
},
"$:/core/ui/Buttons/fold": {
"title": "$:/core/ui/Buttons/fold",
"tags": "$:/tags/ViewToolbar",
"caption": "{{$:/core/images/fold-button}} {{$:/language/Buttons/Fold/Caption}}",
"description": "{{$:/language/Buttons/Fold/Hint}}",
"text": "\\whitespace trim\n<$reveal type=\"nomatch\" stateTitle=<<folded-state>> text=\"hide\" default=\"show\">\n<$button tooltip={{$:/language/Buttons/Fold/Hint}} aria-label={{$:/language/Buttons/Fold/Caption}} class=<<tv-config-toolbar-class>>>\n<$action-sendmessage $message=\"tm-fold-tiddler\" $param=<<currentTiddler>> foldedState=<<folded-state>>/>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\" variable=\"listItem\">\n{{$:/core/images/fold-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\">\n<$text text=\" \"/>\n<$text text={{$:/language/Buttons/Fold/Caption}}/>\n</span>\n</$list>\n</$button>\n</$reveal>\n<$reveal type=\"match\" stateTitle=<<folded-state>> text=\"hide\" default=\"show\">\n<$button tooltip={{$:/language/Buttons/Unfold/Hint}} aria-label={{$:/language/Buttons/Unfold/Caption}} class=<<tv-config-toolbar-class>>>\n<$action-sendmessage $message=\"tm-fold-tiddler\" $param=<<currentTiddler>> foldedState=<<folded-state>>/>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\" variable=\"listItem\">\n{{$:/core/images/unfold-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\">\n<$text text=\" \"/>\n<$text text={{$:/language/Buttons/Unfold/Caption}}/>\n</span>\n</$list>\n</$button>\n</$reveal>\n"
},
"$:/core/ui/Buttons/info": {
"title": "$:/core/ui/Buttons/info",
"tags": "$:/tags/ViewToolbar",
"caption": "{{$:/core/images/info-button}} {{$:/language/Buttons/Info/Caption}}",
"description": "{{$:/language/Buttons/Info/Hint}}",
"text": "\\whitespace trim\n\\define button-content()\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/info-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\">\n<$text text={{$:/language/Buttons/Info/Caption}}/>\n</span>\n</$list>\n\\end\n<$reveal state=\"$:/config/TiddlerInfo/Mode\" type=\"match\" text=\"popup\">\n<$button popup=<<tiddlerInfoState>> tooltip={{$:/language/Buttons/Info/Hint}} aria-label={{$:/language/Buttons/Info/Caption}} class=<<tv-config-toolbar-class>> selectedClass=\"tc-selected\">\n<$macrocall $name=\"button-content\" mode=\"inline\"/>\n</$button>\n</$reveal>\n<$reveal state=\"$:/config/TiddlerInfo/Mode\" type=\"match\" text=\"sticky\">\n<$reveal state=<<tiddlerInfoState>> type=\"match\" text=\"\" default=\"\">\n<$button set=<<tiddlerInfoState>> setTo=\"yes\" tooltip={{$:/language/Buttons/Info/Hint}} aria-label={{$:/language/Buttons/Info/Caption}} class=<<tv-config-toolbar-class>> selectedClass=\"tc-selected\">\n<$macrocall $name=\"button-content\" mode=\"inline\"/>\n</$button>\n</$reveal>\n<$reveal state=<<tiddlerInfoState>> type=\"nomatch\" text=\"\" default=\"\">\n<$button set=<<tiddlerInfoState>> setTo=\"\" tooltip={{$:/language/Buttons/Info/Hint}} aria-label={{$:/language/Buttons/Info/Caption}} class=<<tv-config-toolbar-class>> selectedClass=\"tc-selected\">\n<$macrocall $name=\"button-content\" mode=\"inline\"/>\n</$button>\n</$reveal>\n</$reveal>"
},
"$:/core/ui/Buttons/more-tiddler-actions": {
"title": "$:/core/ui/Buttons/more-tiddler-actions",
"tags": "$:/tags/ViewToolbar",
"caption": "{{$:/core/images/down-arrow}} {{$:/language/Buttons/More/Caption}}",
"description": "{{$:/language/Buttons/More/Hint}}",
"text": "\\whitespace trim\n\\define config-title()\n$:/config/ViewToolbarButtons/Visibility/$(listItem)$\n\\end\n<$button popup=<<qualify \"$:/state/popup/more\">> tooltip={{$:/language/Buttons/More/Hint}} aria-label={{$:/language/Buttons/More/Caption}} class=<<tv-config-toolbar-class>> selectedClass=\"tc-selected\">\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/down-arrow}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\">\n<$text text=\" \"/>\n<$text text={{$:/language/Buttons/More/Caption}}/>\n</span>\n</$list>\n</$button>\n<$reveal state=<<qualify \"$:/state/popup/more\">> type=\"popup\" position=\"belowleft\" animate=\"yes\">\n\n<div class=\"tc-drop-down\">\n\n<$set name=\"tv-config-toolbar-icons\" value=\"yes\">\n\n<$set name=\"tv-config-toolbar-text\" value=\"yes\">\n\n<$set name=\"tv-config-toolbar-class\" value=\"tc-btn-invisible\">\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/ViewToolbar]!has[draft.of]] -[[$:/core/ui/Buttons/more-tiddler-actions]]\" variable=\"listItem\">\n\n<$reveal type=\"match\" state=<<config-title>> text=\"hide\">\n\n<$set name=\"tv-config-toolbar-class\" filter=\"[<tv-config-toolbar-class>] [<listItem>encodeuricomponent[]addprefix[tc-btn-]]\">\n\n<$transclude tiddler=<<listItem>> mode=\"inline\"/>\n\n</$set>\n\n</$reveal>\n\n</$list>\n\n</$set>\n\n</$set>\n\n</$set>\n\n</div>\n\n</$reveal>"
},
"$:/core/ui/Buttons/new-here": {
"title": "$:/core/ui/Buttons/new-here",
"tags": "$:/tags/ViewToolbar",
"caption": "{{$:/core/images/new-here-button}} {{$:/language/Buttons/NewHere/Caption}}",
"description": "{{$:/language/Buttons/NewHere/Hint}}",
"text": "\\whitespace trim\n\\define newHereButtonTags()\n[[$(currentTiddler)$]]\n\\end\n\\define newHereButton()\n<$button tooltip={{$:/language/Buttons/NewHere/Hint}} aria-label={{$:/language/Buttons/NewHere/Caption}} class=<<tv-config-toolbar-class>>>\n<$action-sendmessage $message=\"tm-new-tiddler\" tags=<<newHereButtonTags>>/>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/new-here-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\">\n<$text text={{$:/language/Buttons/NewHere/Caption}}/>\n</span>\n</$list>\n</$button>\n\\end\n<<newHereButton>>"
},
"$:/core/ui/Buttons/new-journal-here": {
"title": "$:/core/ui/Buttons/new-journal-here",
"tags": "$:/tags/ViewToolbar",
"caption": "{{$:/core/images/new-journal-button}} {{$:/language/Buttons/NewJournalHere/Caption}}",
"description": "{{$:/language/Buttons/NewJournalHere/Hint}}",
"text": "\\whitespace trim\n\\define journalButtonTags()\n[[$(currentTiddlerTag)$]] $(journalTags)$\n\\end\n\\define journalButton()\n<$button tooltip={{$:/language/Buttons/NewJournalHere/Hint}} aria-label={{$:/language/Buttons/NewJournalHere/Caption}} class=<<tv-config-toolbar-class>>>\n<$wikify name=\"journalTitle\" text=\"\"\"<$macrocall $name=\"now\" format=<<journalTitleTemplate>>/>\"\"\">\n<$action-sendmessage $message=\"tm-new-tiddler\" title=<<journalTitle>> tags=<<journalButtonTags>>/>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/new-journal-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\">\n<$text text={{$:/language/Buttons/NewJournalHere/Caption}}/>\n</span>\n</$list>\n</$wikify>\n</$button>\n\\end\n<$set name=\"journalTitleTemplate\" value={{$:/config/NewJournal/Title}}>\n<$set name=\"journalTags\" value={{$:/config/NewJournal/Tags}}>\n<$set name=\"currentTiddlerTag\" value=<<currentTiddler>>>\n<<journalButton>>\n</$set>\n</$set>\n</$set>"
},
"$:/core/ui/Buttons/open-window": {
"title": "$:/core/ui/Buttons/open-window",
"tags": "$:/tags/ViewToolbar",
"caption": "{{$:/core/images/open-window}} {{$:/language/Buttons/OpenWindow/Caption}}",
"description": "{{$:/language/Buttons/OpenWindow/Hint}}",
"text": "\\whitespace trim\n<$button message=\"tm-open-window\" tooltip={{$:/language/Buttons/OpenWindow/Hint}} aria-label={{$:/language/Buttons/OpenWindow/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/open-window}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\">\n<$text text=\" \"/>\n<$text text={{$:/language/Buttons/OpenWindow/Caption}}/>\n</span>\n</$list>\n</$button>"
},
"$:/core/ui/Buttons/permalink": {
"title": "$:/core/ui/Buttons/permalink",
"tags": "$:/tags/ViewToolbar",
"caption": "{{$:/core/images/permalink-button}} {{$:/language/Buttons/Permalink/Caption}}",
"description": "{{$:/language/Buttons/Permalink/Hint}}",
"text": "\\whitespace trim\n<$button message=\"tm-permalink\" tooltip={{$:/language/Buttons/Permalink/Hint}} aria-label={{$:/language/Buttons/Permalink/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/permalink-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\">\n<$text text=\" \"/>\n<$text text={{$:/language/Buttons/Permalink/Caption}}/>\n</span>\n</$list>\n</$button>"
},
"$:/core/ui/Buttons/permaview": {
"title": "$:/core/ui/Buttons/permaview",
"tags": "$:/tags/ViewToolbar $:/tags/PageControls",
"caption": "{{$:/core/images/permaview-button}} {{$:/language/Buttons/Permaview/Caption}}",
"description": "{{$:/language/Buttons/Permaview/Hint}}",
"text": "\\whitespace trim\n<$button message=\"tm-permaview\" tooltip={{$:/language/Buttons/Permaview/Hint}} aria-label={{$:/language/Buttons/Permaview/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/permaview-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\">\n<$text text=\" \"/>\n<$text text={{$:/language/Buttons/Permaview/Caption}}/>\n</span>\n</$list>\n</$button>"
},
"$:/DefaultTiddlers": {
"title": "$:/DefaultTiddlers",
"text": "GettingStarted\n"
},
"$:/temp/advancedsearch": {
"title": "$:/temp/advancedsearch",
"text": ""
},
"$:/snippets/allfields": {
"title": "$:/snippets/allfields",
"text": "\\define renderfield(title)\n<tr class=\"tc-view-field\"><td class=\"tc-view-field-name\">''$title$'':</td><td class=\"tc-view-field-value\">//{{$:/language/Docs/Fields/$title$}}//</td></tr>\n\\end\n<table class=\"tc-view-field-table\"><tbody><$list filter=\"[fields[]sort[title]]\" variable=\"listItem\"><$macrocall $name=\"renderfield\" title=<<listItem>>/></$list>\n</tbody></table>\n"
},
"$:/config/AnimationDuration": {
"title": "$:/config/AnimationDuration",
"text": "400"
},
"$:/config/AutoSave": {
"title": "$:/config/AutoSave",
"text": "yes"
},
"$:/config/BitmapEditor/Colour": {
"title": "$:/config/BitmapEditor/Colour",
"text": "#444"
},
"$:/config/BitmapEditor/ImageSizes": {
"title": "$:/config/BitmapEditor/ImageSizes",
"text": "[[62px 100px]] [[100px 62px]] [[124px 200px]] [[200px 124px]] [[248px 400px]] [[371px 600px]] [[400px 248px]] [[556px 900px]] [[600px 371px]] [[742px 1200px]] [[900px 556px]] [[1200px 742px]]"
},
"$:/config/BitmapEditor/LineWidth": {
"title": "$:/config/BitmapEditor/LineWidth",
"text": "3px"
},
"$:/config/BitmapEditor/LineWidths": {
"title": "$:/config/BitmapEditor/LineWidths",
"text": "0.25px 0.5px 1px 2px 3px 4px 6px 8px 10px 16px 20px 28px 40px 56px 80px"
},
"$:/config/BitmapEditor/Opacities": {
"title": "$:/config/BitmapEditor/Opacities",
"text": "0.01 0.025 0.05 0.075 0.1 0.15 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0"
},
"$:/config/BitmapEditor/Opacity": {
"title": "$:/config/BitmapEditor/Opacity",
"text": "1.0"
},
"$:/config/DefaultMoreSidebarTab": {
"title": "$:/config/DefaultMoreSidebarTab",
"text": "$:/core/ui/MoreSideBar/Tags"
},
"$:/config/DefaultSidebarTab": {
"title": "$:/config/DefaultSidebarTab",
"text": "$:/core/ui/SideBar/Open"
},
"$:/config/DownloadSaver/AutoSave": {
"title": "$:/config/DownloadSaver/AutoSave",
"text": "no"
},
"$:/config/Drafts/TypingTimeout": {
"title": "$:/config/Drafts/TypingTimeout",
"text": "400"
},
"$:/config/EditTemplateFields/Visibility/title": {
"title": "$:/config/EditTemplateFields/Visibility/title",
"text": "hide"
},
"$:/config/EditTemplateFields/Visibility/tags": {
"title": "$:/config/EditTemplateFields/Visibility/tags",
"text": "hide"
},
"$:/config/EditTemplateFields/Visibility/text": {
"title": "$:/config/EditTemplateFields/Visibility/text",
"text": "hide"
},
"$:/config/EditTemplateFields/Visibility/creator": {
"title": "$:/config/EditTemplateFields/Visibility/creator",
"text": "hide"
},
"$:/config/EditTemplateFields/Visibility/created": {
"title": "$:/config/EditTemplateFields/Visibility/created",
"text": "hide"
},
"$:/config/EditTemplateFields/Visibility/modified": {
"title": "$:/config/EditTemplateFields/Visibility/modified",
"text": "hide"
},
"$:/config/EditTemplateFields/Visibility/modifier": {
"title": "$:/config/EditTemplateFields/Visibility/modifier",
"text": "hide"
},
"$:/config/EditTemplateFields/Visibility/type": {
"title": "$:/config/EditTemplateFields/Visibility/type",
"text": "hide"
},
"$:/config/EditTemplateFields/Visibility/draft.title": {
"title": "$:/config/EditTemplateFields/Visibility/draft.title",
"text": "hide"
},
"$:/config/EditTemplateFields/Visibility/draft.of": {
"title": "$:/config/EditTemplateFields/Visibility/draft.of",
"text": "hide"
},
"$:/config/EditTemplateFields/Visibility/revision": {
"title": "$:/config/EditTemplateFields/Visibility/revision",
"text": "hide"
},
"$:/config/EditTemplateFields/Visibility/bag": {
"title": "$:/config/EditTemplateFields/Visibility/bag",
"text": "hide"
},
"$:/config/EditorToolbarButtons/Visibility/$:/core/ui/EditorToolbar/heading-4": {
"title": "$:/config/EditorToolbarButtons/Visibility/$:/core/ui/EditorToolbar/heading-4",
"text": "hide"
},
"$:/config/EditorToolbarButtons/Visibility/$:/core/ui/EditorToolbar/heading-5": {
"title": "$:/config/EditorToolbarButtons/Visibility/$:/core/ui/EditorToolbar/heading-5",
"text": "hide"
},
"$:/config/EditorToolbarButtons/Visibility/$:/core/ui/EditorToolbar/heading-6": {
"title": "$:/config/EditorToolbarButtons/Visibility/$:/core/ui/EditorToolbar/heading-6",
"text": "hide"
},
"$:/config/EditorTypeMappings/image/gif": {
"title": "$:/config/EditorTypeMappings/image/gif",
"text": "bitmap"
},
"$:/config/EditorTypeMappings/image/webp": {
"title": "$:/config/EditorTypeMappings/image/webp",
"text": "bitmap"
},
"$:/config/EditorTypeMappings/image/heic": {
"title": "$:/config/EditorTypeMappings/image/heic",
"text": "bitmap"
},
"$:/config/EditorTypeMappings/image/heif": {
"title": "$:/config/EditorTypeMappings/image/heif",
"text": "bitmap"
},
"$:/config/EditorTypeMappings/image/jpeg": {
"title": "$:/config/EditorTypeMappings/image/jpeg",
"text": "bitmap"
},
"$:/config/EditorTypeMappings/image/jpg": {
"title": "$:/config/EditorTypeMappings/image/jpg",
"text": "bitmap"
},
"$:/config/EditorTypeMappings/image/png": {
"title": "$:/config/EditorTypeMappings/image/png",
"text": "bitmap"
},
"$:/config/EditorTypeMappings/image/x-icon": {
"title": "$:/config/EditorTypeMappings/image/x-icon",
"text": "bitmap"
},
"$:/config/EditorTypeMappings/text/vnd.tiddlywiki": {
"title": "$:/config/EditorTypeMappings/text/vnd.tiddlywiki",
"text": "text"
},
"$:/config/Manager/Show": {
"title": "$:/config/Manager/Show",
"text": "tiddlers"
},
"$:/config/Manager/Filter": {
"title": "$:/config/Manager/Filter",
"text": ""
},
"$:/config/Manager/Order": {
"title": "$:/config/Manager/Order",
"text": "forward"
},
"$:/config/Manager/Sort": {
"title": "$:/config/Manager/Sort",
"text": "title"
},
"$:/config/Manager/System": {
"title": "$:/config/Manager/System",
"text": "system"
},
"$:/config/Manager/Tag": {
"title": "$:/config/Manager/Tag",
"text": ""
},
"$:/state/popup/manager/item/$:/Manager/ItemMain/RawText": {
"title": "$:/state/popup/manager/item/$:/Manager/ItemMain/RawText",
"text": "hide"
},
"$:/config/MissingLinks": {
"title": "$:/config/MissingLinks",
"text": "yes"
},
"$:/config/Navigation/UpdateAddressBar": {
"title": "$:/config/Navigation/UpdateAddressBar",
"text": "no"
},
"$:/config/Navigation/UpdateHistory": {
"title": "$:/config/Navigation/UpdateHistory",
"text": "no"
},
"$:/config/NewImageType": {
"title": "$:/config/NewImageType",
"text": "jpeg"
},
"$:/config/OfficialPluginLibrary": {
"title": "$:/config/OfficialPluginLibrary",
"tags": "$:/tags/PluginLibrary",
"url": "https://tiddlywiki.com/library/v5.1.19/index.html",
"caption": "{{$:/language/OfficialPluginLibrary}}",
"text": "{{$:/language/OfficialPluginLibrary/Hint}}\n"
},
"$:/config/Navigation/openLinkFromInsideRiver": {
"title": "$:/config/Navigation/openLinkFromInsideRiver",
"text": "below"
},
"$:/config/Navigation/openLinkFromOutsideRiver": {
"title": "$:/config/Navigation/openLinkFromOutsideRiver",
"text": "top"
},
"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/advanced-search": {
"title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/advanced-search",
"text": "hide"
},
"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/close-all": {
"title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/close-all",
"text": "hide"
},
"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/encryption": {
"title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/encryption",
"text": "hide"
},
"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/export-page": {
"title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/export-page",
"text": "hide"
},
"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/fold-all": {
"title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/fold-all",
"text": "hide"
},
"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/full-screen": {
"title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/full-screen",
"text": "hide"
},
"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/home": {
"title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/home",
"text": "hide"
},
"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/refresh": {
"title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/refresh",
"text": "hide"
},
"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/import": {
"title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/import",
"text": "hide"
},
"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/language": {
"title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/language",
"text": "hide"
},
"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/tag-manager": {
"title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/tag-manager",
"text": "hide"
},
"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/manager": {
"title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/manager",
"text": "hide"
},
"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/more-page-actions": {
"title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/more-page-actions",
"text": "hide"
},
"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/new-journal": {
"title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/new-journal",
"text": "hide"
},
"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/new-image": {
"title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/new-image",
"text": "hide"
},
"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/palette": {
"title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/palette",
"text": "hide"
},
"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/permaview": {
"title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/permaview",
"text": "hide"
},
"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/print": {
"title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/print",
"text": "hide"
},
"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/storyview": {
"title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/storyview",
"text": "hide"
},
"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/timestamp": {
"title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/timestamp",
"text": "hide"
},
"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/theme": {
"title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/theme",
"text": "hide"
},
"$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/unfold-all": {
"title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/unfold-all",
"text": "hide"
},
"$:/config/Performance/Instrumentation": {
"title": "$:/config/Performance/Instrumentation",
"text": "no"
},
"$:/config/SaveWikiButton/Template": {
"title": "$:/config/SaveWikiButton/Template",
"text": "$:/core/save/all"
},
"$:/config/SaverFilter": {
"title": "$:/config/SaverFilter",
"text": "[all[]] -[[$:/HistoryList]] -[[$:/StoryList]] -[[$:/Import]] -[[$:/isEncrypted]] -[[$:/UploadName]] -[prefix[$:/state/]] -[prefix[$:/temp/]]"
},
"$:/config/Search/AutoFocus": {
"title": "$:/config/Search/AutoFocus",
"text": "true"
},
"$:/config/Search/MinLength": {
"title": "$:/config/Search/MinLength",
"text": "3"
},
"$:/config/SearchResults/Default": {
"title": "$:/config/SearchResults/Default",
"text": "$:/core/ui/DefaultSearchResultList"
},
"$:/config/ShortcutInfo/bold": {
"title": "$:/config/ShortcutInfo/bold",
"text": "{{$:/language/Buttons/Bold/Hint}}"
},
"$:/config/ShortcutInfo/cancel-edit-tiddler": {
"title": "$:/config/ShortcutInfo/cancel-edit-tiddler",
"text": "{{$:/language/Buttons/Cancel/Hint}}"
},
"$:/config/ShortcutInfo/excise": {
"title": "$:/config/ShortcutInfo/excise",
"text": "{{$:/language/Buttons/Excise/Hint}}"
},
"$:/config/ShortcutInfo/heading-1": {
"title": "$:/config/ShortcutInfo/heading-1",
"text": "{{$:/language/Buttons/Heading1/Hint}}"
},
"$:/config/ShortcutInfo/heading-2": {
"title": "$:/config/ShortcutInfo/heading-2",
"text": "{{$:/language/Buttons/Heading2/Hint}}"
},
"$:/config/ShortcutInfo/heading-3": {
"title": "$:/config/ShortcutInfo/heading-3",
"text": "{{$:/language/Buttons/Heading3/Hint}}"
},
"$:/config/ShortcutInfo/heading-4": {
"title": "$:/config/ShortcutInfo/heading-4",
"text": "{{$:/language/Buttons/Heading4/Hint}}"
},
"$:/config/ShortcutInfo/heading-5": {
"title": "$:/config/ShortcutInfo/heading-5",
"text": "{{$:/language/Buttons/Heading5/Hint}}"
},
"$:/config/ShortcutInfo/heading-6": {
"title": "$:/config/ShortcutInfo/heading-6",
"text": "{{$:/language/Buttons/Heading6/Hint}}"
},
"$:/config/ShortcutInfo/italic": {
"title": "$:/config/ShortcutInfo/italic",
"text": "{{$:/language/Buttons/Italic/Hint}}"
},
"$:/config/ShortcutInfo/link": {
"title": "$:/config/ShortcutInfo/link",
"text": "{{$:/language/Buttons/Link/Hint}}"
},
"$:/config/ShortcutInfo/list-bullet": {
"title": "$:/config/ShortcutInfo/list-bullet",
"text": "{{$:/language/Buttons/ListBullet/Hint}}"
},
"$:/config/ShortcutInfo/list-number": {
"title": "$:/config/ShortcutInfo/list-number",
"text": "{{$:/language/Buttons/ListNumber/Hint}}"
},
"$:/config/ShortcutInfo/mono-block": {
"title": "$:/config/ShortcutInfo/mono-block",
"text": "{{$:/language/Buttons/MonoBlock/Hint}}"
},
"$:/config/ShortcutInfo/mono-line": {
"title": "$:/config/ShortcutInfo/mono-line",
"text": "{{$:/language/Buttons/MonoLine/Hint}}"
},
"$:/config/ShortcutInfo/new-image": {
"title": "$:/config/ShortcutInfo/new-image",
"text": "{{$:/language/Buttons/NewImage/Hint}}"
},
"$:/config/ShortcutInfo/new-journal": {
"title": "$:/config/ShortcutInfo/new-journal",
"text": "{{$:/language/Buttons/NewJournal/Hint}}"
},
"$:/config/ShortcutInfo/new-tiddler": {
"title": "$:/config/ShortcutInfo/new-tiddler",
"text": "{{$:/language/Buttons/NewTiddler/Hint}}"
},
"$:/config/ShortcutInfo/picture": {
"title": "$:/config/ShortcutInfo/picture",
"text": "{{$:/language/Buttons/Picture/Hint}}"
},
"$:/config/ShortcutInfo/preview": {
"title": "$:/config/ShortcutInfo/preview",
"text": "{{$:/language/Buttons/Preview/Hint}}"
},
"$:/config/ShortcutInfo/quote": {
"title": "$:/config/ShortcutInfo/quote",
"text": "{{$:/language/Buttons/Quote/Hint}}"
},
"$:/config/ShortcutInfo/save-tiddler": {
"title": "$:/config/ShortcutInfo/save-tiddler",
"text": "{{$:/language/Buttons/Save/Hint}}"
},
"$:/config/ShortcutInfo/stamp": {
"title": "$:/config/ShortcutInfo/stamp",
"text": "{{$:/language/Buttons/Stamp/Hint}}"
},
"$:/config/ShortcutInfo/strikethrough": {
"title": "$:/config/ShortcutInfo/strikethrough",
"text": "{{$:/language/Buttons/Strikethrough/Hint}}"
},
"$:/config/ShortcutInfo/subscript": {
"title": "$:/config/ShortcutInfo/subscript",
"text": "{{$:/language/Buttons/Subscript/Hint}}"
},
"$:/config/ShortcutInfo/superscript": {
"title": "$:/config/ShortcutInfo/superscript",
"text": "{{$:/language/Buttons/Superscript/Hint}}"
},
"$:/config/ShortcutInfo/underline": {
"title": "$:/config/ShortcutInfo/underline",
"text": "{{$:/language/Buttons/Underline/Hint}}"
},
"$:/config/SyncFilter": {
"title": "$:/config/SyncFilter",
"text": "[is[tiddler]] -[[$:/HistoryList]] -[[$:/Import]] -[[$:/isEncrypted]] -[prefix[$:/status/]] -[prefix[$:/state/]] -[prefix[$:/temp/]]"
},
"$:/config/Tags/MinLength": {
"title": "$:/config/Tags/MinLength",
"text": "0"
},
"$:/config/TextEditor/EditorHeight/Height": {
"title": "$:/config/TextEditor/EditorHeight/Height",
"text": "400px"
},
"$:/config/TextEditor/EditorHeight/Mode": {
"title": "$:/config/TextEditor/EditorHeight/Mode",
"text": "auto"
},
"$:/config/TiddlerInfo/Default": {
"title": "$:/config/TiddlerInfo/Default",
"text": "$:/core/ui/TiddlerInfo/Fields"
},
"$:/config/TiddlerInfo/Mode": {
"title": "$:/config/TiddlerInfo/Mode",
"text": "popup"
},
"$:/config/Tiddlers/TitleLinks": {
"title": "$:/config/Tiddlers/TitleLinks",
"text": "no"
},
"$:/config/Toolbar/ButtonClass": {
"title": "$:/config/Toolbar/ButtonClass",
"text": "tc-btn-invisible"
},
"$:/config/Toolbar/Icons": {
"title": "$:/config/Toolbar/Icons",
"text": "yes"
},
"$:/config/Toolbar/Text": {
"title": "$:/config/Toolbar/Text",
"text": "no"
},
"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/clone": {
"title": "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/clone",
"text": "hide"
},
"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/close-others": {
"title": "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/close-others",
"text": "hide"
},
"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/export-tiddler": {
"title": "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/export-tiddler",
"text": "hide"
},
"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/info": {
"title": "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/info",
"text": "hide"
},
"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/more-tiddler-actions": {
"title": "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/more-tiddler-actions",
"text": "show"
},
"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/new-here": {
"title": "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/new-here",
"text": "hide"
},
"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/new-journal-here": {
"title": "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/new-journal-here",
"text": "hide"
},
"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/open-window": {
"title": "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/open-window",
"text": "hide"
},
"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/permalink": {
"title": "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/permalink",
"text": "hide"
},
"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/permaview": {
"title": "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/permaview",
"text": "hide"
},
"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/delete": {
"title": "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/delete",
"text": "hide"
},
"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/fold": {
"title": "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/fold",
"text": "hide"
},
"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/fold-bar": {
"title": "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/fold-bar",
"text": "hide"
},
"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/fold-others": {
"title": "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/fold-others",
"text": "hide"
},
"$:/config/shortcuts-mac/bold": {
"title": "$:/config/shortcuts-mac/bold",
"text": "meta-B"
},
"$:/config/shortcuts-mac/italic": {
"title": "$:/config/shortcuts-mac/italic",
"text": "meta-I"
},
"$:/config/shortcuts-mac/underline": {
"title": "$:/config/shortcuts-mac/underline",
"text": "meta-U"
},
"$:/config/shortcuts-mac/new-image": {
"title": "$:/config/shortcuts-mac/new-image",
"text": "ctrl-I"
},
"$:/config/shortcuts-mac/new-journal": {
"title": "$:/config/shortcuts-mac/new-journal",
"text": "ctrl-J"
},
"$:/config/shortcuts-mac/new-tiddler": {
"title": "$:/config/shortcuts-mac/new-tiddler",
"text": "ctrl-N"
},
"$:/config/shortcuts-not-mac/bold": {
"title": "$:/config/shortcuts-not-mac/bold",
"text": "ctrl-B"
},
"$:/config/shortcuts-not-mac/italic": {
"title": "$:/config/shortcuts-not-mac/italic",
"text": "ctrl-I"
},
"$:/config/shortcuts-not-mac/underline": {
"title": "$:/config/shortcuts-not-mac/underline",
"text": "ctrl-U"
},
"$:/config/shortcuts-not-mac/new-image": {
"title": "$:/config/shortcuts-not-mac/new-image",
"text": "alt-I"
},
"$:/config/shortcuts-not-mac/new-journal": {
"title": "$:/config/shortcuts-not-mac/new-journal",
"text": "alt-J"
},
"$:/config/shortcuts-not-mac/new-tiddler": {
"title": "$:/config/shortcuts-not-mac/new-tiddler",
"text": "alt-N"
},
"$:/config/shortcuts/cancel-edit-tiddler": {
"title": "$:/config/shortcuts/cancel-edit-tiddler",
"text": "escape"
},
"$:/config/shortcuts/excise": {
"title": "$:/config/shortcuts/excise",
"text": "ctrl-E"
},
"$:/config/shortcuts/heading-1": {
"title": "$:/config/shortcuts/heading-1",
"text": "ctrl-1"
},
"$:/config/shortcuts/heading-2": {
"title": "$:/config/shortcuts/heading-2",
"text": "ctrl-2"
},
"$:/config/shortcuts/heading-3": {
"title": "$:/config/shortcuts/heading-3",
"text": "ctrl-3"
},
"$:/config/shortcuts/heading-4": {
"title": "$:/config/shortcuts/heading-4",
"text": "ctrl-4"
},
"$:/config/shortcuts/heading-5": {
"title": "$:/config/shortcuts/heading-5",
"text": "ctrl-5"
},
"$:/config/shortcuts/heading-6": {
"title": "$:/config/shortcuts/heading-6",
"text": "ctrl-6"
},
"$:/config/shortcuts/link": {
"title": "$:/config/shortcuts/link",
"text": "ctrl-L"
},
"$:/config/shortcuts/linkify": {
"title": "$:/config/shortcuts/linkify",
"text": "alt-shift-L"
},
"$:/config/shortcuts/list-bullet": {
"title": "$:/config/shortcuts/list-bullet",
"text": "ctrl-shift-L"
},
"$:/config/shortcuts/list-number": {
"title": "$:/config/shortcuts/list-number",
"text": "ctrl-shift-N"
},
"$:/config/shortcuts/mono-block": {
"title": "$:/config/shortcuts/mono-block",
"text": "ctrl-shift-M"
},
"$:/config/shortcuts/mono-line": {
"title": "$:/config/shortcuts/mono-line",
"text": "ctrl-M"
},
"$:/config/shortcuts/picture": {
"title": "$:/config/shortcuts/picture",
"text": "ctrl-shift-I"
},
"$:/config/shortcuts/preview": {
"title": "$:/config/shortcuts/preview",
"text": "alt-P"
},
"$:/config/shortcuts/quote": {
"title": "$:/config/shortcuts/quote",
"text": "ctrl-Q"
},
"$:/config/shortcuts/save-tiddler": {
"title": "$:/config/shortcuts/save-tiddler",
"text": "ctrl+enter"
},
"$:/config/shortcuts/stamp": {
"title": "$:/config/shortcuts/stamp",
"text": "ctrl-S"
},
"$:/config/shortcuts/strikethrough": {
"title": "$:/config/shortcuts/strikethrough",
"text": "ctrl-T"
},
"$:/config/shortcuts/subscript": {
"title": "$:/config/shortcuts/subscript",
"text": "ctrl-shift-B"
},
"$:/config/shortcuts/superscript": {
"title": "$:/config/shortcuts/superscript",
"text": "ctrl-shift-P"
},
"$:/config/shortcuts/transcludify": {
"title": "$:/config/shortcuts/transcludify",
"text": "alt-shift-T"
},
"$:/config/WikiParserRules/Inline/wikilink": {
"title": "$:/config/WikiParserRules/Inline/wikilink",
"text": "enable"
},
"$:/snippets/currpalettepreview": {
"title": "$:/snippets/currpalettepreview",
"text": "\\define swatchStyle()\nbackground-color: $(swatchColour)$;\n\\end\n\\define swatch()\n<$set name=\"swatchColour\" value={{##$(colour)$}}\n><div class=\"tc-swatch\" style=<<swatchStyle>> title=<<colour>>/></$set>\n\\end\n<div class=\"tc-swatches-horiz\"><$list filter=\"\nforeground\nbackground\nmuted-foreground\nprimary\npage-background\ntab-background\ntiddler-info-background\n\" variable=\"colour\"><<swatch>></$list></div>"
},
"$:/snippets/download-wiki-button": {
"title": "$:/snippets/download-wiki-button",
"text": "\\define lingo-base() $:/language/ControlPanel/Tools/Download/\n<$button class=\"tc-btn-big-green\">\n<$action-sendmessage $message=\"tm-download-file\" $param=\"$:/core/save/all\" filename=\"index.html\"/>\n<<lingo Full/Caption>> {{$:/core/images/save-button}}\n</$button>"
},
"$:/language": {
"title": "$:/language",
"text": "$:/languages/en-GB"
},
"$:/snippets/languageswitcher": {
"title": "$:/snippets/languageswitcher",
"text": "\\define flag-title()\n$(languagePluginTitle)$/icon\n\\end\n\n<$linkcatcher to=\"$:/language\">\n<div class=\"tc-chooser tc-language-chooser\">\n<$list filter=\"[[$:/languages/en-GB]] [plugin-type[language]sort[description]]\">\n<$set name=\"cls\" filter=\"[all[current]field:title{$:/language}]\" value=\"tc-chooser-item tc-chosen\" emptyValue=\"tc-chooser-item\"><div class=<<cls>>>\n<$link>\n<span class=\"tc-image-button\">\n<$set name=\"languagePluginTitle\" value=<<currentTiddler>>>\n<$transclude subtiddler=<<flag-title>>>\n<$list filter=\"[all[current]field:title[$:/languages/en-GB]]\">\n<$transclude tiddler=\"$:/languages/en-GB/icon\"/>\n</$list>\n</$transclude>\n</$set>\n</span>\n<$view field=\"description\">\n<$view field=\"name\">\n<$view field=\"title\"/>\n</$view>\n</$view>\n</$link>\n</div>\n</$set>\n</$list>\n</div>\n</$linkcatcher>"
},
"$:/core/macros/CSS": {
"title": "$:/core/macros/CSS",
"tags": "$:/tags/Macro",
"text": "\\define colour(name)\n<$transclude tiddler={{$:/palette}} index=\"$name$\"><$transclude tiddler=\"$:/palettes/Vanilla\" index=\"$name$\"/></$transclude>\n\\end\n\n\\define color(name)\n<<colour $name$>>\n\\end\n\n\\define box-shadow(shadow)\n``\n -webkit-box-shadow: $shadow$;\n -moz-box-shadow: $shadow$;\n box-shadow: $shadow$;\n``\n\\end\n\n\\define filter(filter)\n``\n -webkit-filter: $filter$;\n -moz-filter: $filter$;\n filter: $filter$;\n``\n\\end\n\n\\define transition(transition)\n``\n -webkit-transition: $transition$;\n -moz-transition: $transition$;\n transition: $transition$;\n``\n\\end\n\n\\define transform-origin(origin)\n``\n -webkit-transform-origin: $origin$;\n -moz-transform-origin: $origin$;\n transform-origin: $origin$;\n``\n\\end\n\n\\define background-linear-gradient(gradient)\n``\nbackground-image: linear-gradient($gradient$);\nbackground-image: -o-linear-gradient($gradient$);\nbackground-image: -moz-linear-gradient($gradient$);\nbackground-image: -webkit-linear-gradient($gradient$);\nbackground-image: -ms-linear-gradient($gradient$);\n``\n\\end\n\n\\define column-count(columns)\n``\n-moz-column-count: $columns$;\n-webkit-column-count: $columns$;\ncolumn-count: $columns$;\n``\n\\end\n\n\\define datauri(title)\n<$macrocall $name=\"makedatauri\" type={{$title$!!type}} text={{$title$}}/>\n\\end\n\n\\define if-sidebar(text)\n<$reveal state=\"$:/state/sidebar\" type=\"match\" text=\"yes\" default=\"yes\">$text$</$reveal>\n\\end\n\n\\define if-no-sidebar(text)\n<$reveal state=\"$:/state/sidebar\" type=\"nomatch\" text=\"yes\" default=\"yes\">$text$</$reveal>\n\\end\n\n\\define if-background-attachment(text)\n<$reveal state=\"$:/themes/tiddlywiki/vanilla/settings/backgroundimage\" type=\"nomatch\" text=\"\">$text$</$reveal>\n\\end\n"
},
"$:/core/macros/colour-picker": {
"title": "$:/core/macros/colour-picker",
"tags": "$:/tags/Macro",
"text": "\\define colour-picker-update-recent()\n<$action-listops\n\t$tiddler=\"$:/config/ColourPicker/Recent\"\n\t$subfilter=\"$(colour-picker-value)$ [list[$:/config/ColourPicker/Recent]remove[$(colour-picker-value)$]] +[limit[8]]\"\n/>\n\\end\n\n\\define colour-picker-inner(actions)\n<$button tag=\"a\" tooltip=\"\"\"$(colour-picker-value)$\"\"\">\n\n$(colour-picker-update-recent)$\n\n$actions$\n\n<div style=\"background-color: $(colour-picker-value)$; width: 100%; height: 100%; border-radius: 50%;\"/>\n\n</$button>\n\\end\n\n\\define colour-picker-recent-inner(actions)\n<$set name=\"colour-picker-value\" value=\"$(recentColour)$\">\n<$macrocall $name=\"colour-picker-inner\" actions=\"\"\"$actions$\"\"\"/>\n</$set>\n\\end\n\n\\define colour-picker-recent(actions)\n{{$:/language/ColourPicker/Recent}} <$list filter=\"[list[$:/config/ColourPicker/Recent]]\" variable=\"recentColour\">\n<$macrocall $name=\"colour-picker-recent-inner\" actions=\"\"\"$actions$\"\"\"/></$list>\n\\end\n\n\\define colour-picker(actions)\n<div class=\"tc-colour-chooser\">\n\n<$macrocall $name=\"colour-picker-recent\" actions=\"\"\"$actions$\"\"\"/>\n\n---\n\n<$list filter=\"LightPink Pink Crimson LavenderBlush PaleVioletRed HotPink DeepPink MediumVioletRed Orchid Thistle Plum Violet Magenta Fuchsia DarkMagenta Purple MediumOrchid DarkViolet DarkOrchid Indigo BlueViolet MediumPurple MediumSlateBlue SlateBlue DarkSlateBlue Lavender GhostWhite Blue MediumBlue MidnightBlue DarkBlue Navy RoyalBlue CornflowerBlue LightSteelBlue LightSlateGrey SlateGrey DodgerBlue AliceBlue SteelBlue LightSkyBlue SkyBlue DeepSkyBlue LightBlue PowderBlue CadetBlue Azure LightCyan PaleTurquoise Cyan Aqua DarkTurquoise DarkSlateGrey DarkCyan Teal MediumTurquoise LightSeaGreen Turquoise Aquamarine MediumAquamarine MediumSpringGreen MintCream SpringGreen MediumSeaGreen SeaGreen Honeydew LightGreen PaleGreen DarkSeaGreen LimeGreen Lime ForestGreen Green DarkGreen Chartreuse LawnGreen GreenYellow DarkOliveGreen YellowGreen OliveDrab Beige LightGoldenrodYellow Ivory LightYellow Yellow Olive DarkKhaki LemonChiffon PaleGoldenrod Khaki Gold Cornsilk Goldenrod DarkGoldenrod FloralWhite OldLace Wheat Moccasin Orange PapayaWhip BlanchedAlmond NavajoWhite AntiqueWhite Tan BurlyWood Bisque DarkOrange Linen Peru PeachPuff SandyBrown Chocolate SaddleBrown Seashell Sienna LightSalmon Coral OrangeRed DarkSalmon Tomato MistyRose Salmon Snow LightCoral RosyBrown IndianRed Red Brown FireBrick DarkRed Maroon White WhiteSmoke Gainsboro LightGrey Silver DarkGrey Grey DimGrey Black\" variable=\"colour-picker-value\">\n<$macrocall $name=\"colour-picker-inner\" actions=\"\"\"$actions$\"\"\"/>\n</$list>\n\n---\n\n<$edit-text tiddler=\"$:/config/ColourPicker/New\" tag=\"input\" default=\"\" placeholder=\"\"/> \n<$edit-text tiddler=\"$:/config/ColourPicker/New\" type=\"color\" tag=\"input\"/>\n<$set name=\"colour-picker-value\" value={{$:/config/ColourPicker/New}}>\n<$macrocall $name=\"colour-picker-inner\" actions=\"\"\"$actions$\"\"\"/>\n</$set>\n\n</div>\n\n\\end\n"
},
"$:/core/macros/copy-to-clipboard": {
"title": "$:/core/macros/copy-to-clipboard",
"tags": "$:/tags/Macro",
"text": "\\define copy-to-clipboard(src,class:\"tc-btn-invisible\",style)\n<$button class=<<__class__>> style=<<__style__>> message=\"tm-copy-to-clipboard\" param=<<__src__>> tooltip={{$:/language/Buttons/CopyToClipboard/Hint}}>\n{{$:/core/images/copy-clipboard}} <$text text={{$:/language/Buttons/CopyToClipboard/Caption}}/>\n</$button>\n\\end\n\n\\define copy-to-clipboard-above-right(src,class:\"tc-btn-invisible\",style)\n<div style=\"position: relative;\">\n<div style=\"position: absolute; bottom: 0; right: 0;\">\n<$macrocall $name=\"copy-to-clipboard\" src=<<__src__>> class=<<__class__>> style=<<__style__>>/>\n</div>\n</div>\n\\end\n\n"
},
"$:/core/macros/diff": {
"title": "$:/core/macros/diff",
"tags": "$:/tags/Macro",
"text": "\\define compareTiddlerText(sourceTiddlerTitle,sourceSubTiddlerTitle,destTiddlerTitle,destSubTiddlerTitle)\n<$set name=\"source\" tiddler=<<__sourceTiddlerTitle__>> subtiddler=<<__sourceSubTiddlerTitle__>>>\n<$set name=\"dest\" tiddler=<<__destTiddlerTitle__>> subtiddler=<<__destSubTiddlerTitle__>>>\n<$diff-text source=<<source>> dest=<<dest>>/>\n</$set>\n</$set>\n\\end\n\n\\define compareTiddlers(sourceTiddlerTitle,sourceSubTiddlerTitle,destTiddlerTitle,destSubTiddlerTitle,exclude)\n<table class=\"tc-diff-tiddlers\">\n<tbody>\n<$set name=\"sourceFields\" filter=\"[<__sourceTiddlerTitle__>fields[]sort[]]\">\n<$set name=\"destFields\" filter=\"[<__destSubTiddlerTitle__>subtiddlerfields<__destTiddlerTitle__>sort[]]\">\n<$list filter=\"[enlist<sourceFields>] [enlist<destFields>] -[enlist<__exclude__>] +[sort[]]\" variable=\"fieldName\">\n<tr>\n<th>\n<$text text=<<fieldName>>/> \n</th>\n<td>\n<$set name=\"source\" tiddler=<<__sourceTiddlerTitle__>> subtiddler=<<__sourceSubTiddlerTitle__>> field=<<fieldName>>>\n<$set name=\"dest\" tiddler=<<__destTiddlerTitle__>> subtiddler=<<__destSubTiddlerTitle__>> field=<<fieldName>>>\n<$diff-text source=<<source>> dest=<<dest>>>\n</$diff-text>\n</$set>\n</$set>\n</td>\n</tr>\n</$list>\n</$set>\n</$set>\n</tbody>\n</table>\n\\end\n"
},
"$:/core/macros/export": {
"title": "$:/core/macros/export",
"tags": "$:/tags/Macro",
"text": "\\define exportButtonFilename(baseFilename)\n$baseFilename$$(extension)$\n\\end\n\n\\define exportButton(exportFilter:\"[!is[system]sort[title]]\",lingoBase,baseFilename:\"tiddlers\")\n<span class=\"tc-popup-keep\"><$button popup=<<qualify \"$:/state/popup/export\">> tooltip={{$lingoBase$Hint}} aria-label={{$lingoBase$Caption}} class=<<tv-config-toolbar-class>> selectedClass=\"tc-selected\">\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/export-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$lingoBase$Caption}}/></span>\n</$list>\n</$button></span><$reveal state=<<qualify \"$:/state/popup/export\">> type=\"popup\" position=\"below\" animate=\"yes\">\n<div class=\"tc-drop-down\">\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/Exporter]]\">\n<$set name=\"extension\" value={{!!extension}}>\n<$button class=\"tc-btn-invisible\">\n<$action-sendmessage $message=\"tm-download-file\" $param=<<currentTiddler>> exportFilter=\"\"\"$exportFilter$\"\"\" filename=<<exportButtonFilename \"\"\"$baseFilename$\"\"\">>/>\n<$action-deletetiddler $tiddler=<<qualify \"$:/state/popup/export\">>/>\n<$transclude field=\"description\"/>\n</$button>\n</$set>\n</$list>\n</div>\n</$reveal>\n\\end\n"
},
"$:/core/macros/image-picker": {
"title": "$:/core/macros/image-picker",
"created": "20170715180840889",
"modified": "20170715180914005",
"tags": "$:/tags/Macro",
"type": "text/vnd.tiddlywiki",
"text": "\\define image-picker-thumbnail(actions)\n<$button tag=\"a\" tooltip=\"\"\"$(imageTitle)$\"\"\">\n$actions$\n<$transclude tiddler=<<imageTitle>>/>\n</$button>\n\\end\n\n\\define image-picker-list(filter,actions)\n<$list filter=\"\"\"$filter$\"\"\" variable=\"imageTitle\">\n<$macrocall $name=\"image-picker-thumbnail\" actions=\"\"\"$actions$\"\"\"/>\n</$list>\n\\end\n\n\\define image-picker(actions,filter:\"[all[shadows+tiddlers]is[image]] -[type[application/pdf]] +[!has[draft.of]$subfilter$sort[title]]\",subfilter:\"\")\n<div class=\"tc-image-chooser\">\n<$vars state-system=<<qualify \"$:/state/image-picker/system\">>>\n<$checkbox tiddler=<<state-system>> field=\"text\" checked=\"show\" unchecked=\"hide\" default=\"hide\">\n{{$:/language/SystemTiddlers/Include/Prompt}}\n</$checkbox>\n<$reveal state=<<state-system>> type=\"match\" text=\"hide\" default=\"hide\" tag=\"div\">\n<$macrocall $name=\"image-picker-list\" filter=\"\"\"$filter$ +[!is[system]]\"\"\" actions=\"\"\"$actions$\"\"\"/>\n</$reveal>\n<$reveal state=<<state-system>> type=\"nomatch\" text=\"hide\" default=\"hide\" tag=\"div\">\n<$macrocall $name=\"image-picker-list\" filter=\"\"\"$filter$\"\"\" actions=\"\"\"$actions$\"\"\"/>\n</$reveal>\n</$vars>\n</div>\n\\end\n\n\\define image-picker-include-tagged-images(actions)\n<$macrocall $name=\"image-picker\" filter=\"[all[shadows+tiddlers]is[image]] [all[shadows+tiddlers]tag[$:/tags/Image]] -[type[application/pdf]] +[!has[draft.of]sort[title]]\" actions=\"\"\"$actions$\"\"\"/>\n\\end\n"
},
"$:/core/macros/lingo": {
"title": "$:/core/macros/lingo",
"tags": "$:/tags/Macro",
"text": "\\define lingo-base()\n$:/language/\n\\end\n\n\\define lingo(title)\n{{$(lingo-base)$$title$}}\n\\end\n"
},
"$:/core/macros/list": {
"title": "$:/core/macros/list",
"tags": "$:/tags/Macro",
"text": "\\define list-links(filter,type:\"ul\",subtype:\"li\",class:\"\",emptyMessage)\n<$type$ class=\"$class$\">\n<$list filter=\"$filter$\" emptyMessage=<<__emptyMessage__>>>\n<$subtype$>\n<$link to={{!!title}}>\n<$transclude field=\"caption\">\n<$view field=\"title\"/>\n</$transclude>\n</$link>\n</$subtype$>\n</$list>\n</$type$>\n\\end\n\n\\define list-links-draggable-drop-actions()\n<$action-listops $tiddler=<<targetTiddler>> $field=<<targetField>> $subfilter=\"+[insertbefore:currentTiddler<actionTiddler>]\"/>\n\\end\n\n\\define list-links-draggable(tiddler,field:\"list\",type:\"ul\",subtype:\"li\",class:\"\",itemTemplate)\n<$vars targetTiddler=\"\"\"$tiddler$\"\"\" targetField=\"\"\"$field$\"\"\">\n<$type$ class=\"$class$\">\n<$list filter=\"[list[$tiddler$!!$field$]]\">\n<$droppable actions=<<list-links-draggable-drop-actions>> tag=\"\"\"$subtype$\"\"\">\n<div class=\"tc-droppable-placeholder\">\n \n</div>\n<div>\n<$transclude tiddler=\"\"\"$itemTemplate$\"\"\">\n<$link to={{!!title}}>\n<$transclude field=\"caption\">\n<$view field=\"title\"/>\n</$transclude>\n</$link>\n</$transclude>\n</div>\n</$droppable>\n</$list>\n</$type$>\n<$tiddler tiddler=\"\">\n<$droppable actions=<<list-links-draggable-drop-actions>> tag=\"div\">\n<div class=\"tc-droppable-placeholder\">\n \n</div>\n<div style=\"height:0.5em;\"/>\n</$droppable>\n</$tiddler>\n</$vars>\n\\end\n\n\\define list-tagged-draggable-drop-actions(tag)\n<!-- Save the current ordering of the tiddlers with this tag -->\n<$set name=\"order\" filter=\"[<__tag__>tagging[]]\">\n<!-- Remove any list-after or list-before fields from the tiddlers with this tag -->\n<$list filter=\"[<__tag__>tagging[]]\">\n<$action-deletefield $field=\"list-before\"/>\n<$action-deletefield $field=\"list-after\"/>\n</$list>\n<!-- Save the new order to the Tag Tiddler -->\n<$action-listops $tiddler=<<__tag__>> $field=\"list\" $filter=\"+[enlist<order>] +[insertbefore:currentTiddler<actionTiddler>]\"/>\n<!-- Make sure the newly added item has the right tag -->\n<!-- Removing this line makes dragging tags within the dropdown work as intended -->\n<!--<$action-listops $tiddler=<<actionTiddler>> $tags=<<__tag__>>/>-->\n<!-- Using the following 5 lines as replacement makes dragging titles from outside into the dropdown apply the tag -->\n<$list filter=\"[<actionTiddler>!contains:tags<__tag__>]\">\n<$fieldmangler tiddler=<<actionTiddler>>>\n<$action-sendmessage $message=\"tm-add-tag\" $param=<<__tag__>>/>\n</$fieldmangler>\n</$list>\n</$set>\n\\end\n\n\\define list-tagged-draggable(tag,subFilter,emptyMessage,itemTemplate,elementTag:\"div\")\n<$set name=\"tag\" value=<<__tag__>>>\n<$list filter=\"[<__tag__>tagging[]$subFilter$]\" emptyMessage=<<__emptyMessage__>>>\n<$elementTag$ class=\"tc-menu-list-item\">\n<$droppable actions=\"\"\"<$macrocall $name=\"list-tagged-draggable-drop-actions\" tag=<<__tag__>>/>\"\"\">\n<$elementTag$ class=\"tc-droppable-placeholder\">\n \n</$elementTag$>\n<$elementTag$>\n<$transclude tiddler=\"\"\"$itemTemplate$\"\"\">\n<$link to={{!!title}}>\n<$view field=\"title\"/>\n</$link>\n</$transclude>\n</$elementTag$>\n</$droppable>\n</$elementTag$>\n</$list>\n<$tiddler tiddler=\"\">\n<$droppable actions=\"\"\"<$macrocall $name=\"list-tagged-draggable-drop-actions\" tag=<<__tag__>>/>\"\"\">\n<$elementTag$ class=\"tc-droppable-placeholder\">\n \n</$elementTag$>\n<$elementTag$ style=\"height:0.5em;\">\n</$elementTag$>\n</$droppable>\n</$tiddler>\n</$set>\n\\end\n"
},
"$:/core/macros/tabs": {
"title": "$:/core/macros/tabs",
"tags": "$:/tags/Macro",
"text": "\\define tabs(tabsList,default,state:\"$:/state/tab\",class,template,buttonTemplate,retain)\n<div class=\"tc-tab-set $class$\">\n<div class=\"tc-tab-buttons $class$\">\n<$list filter=\"$tabsList$\" variable=\"currentTab\"><$set name=\"save-currentTiddler\" value=<<currentTiddler>>><$tiddler tiddler=<<currentTab>>><$button set=<<qualify \"$state$\">> setTo=<<currentTab>> default=\"$default$\" selectedClass=\"tc-tab-selected\" tooltip={{!!tooltip}}>\n<$tiddler tiddler=<<save-currentTiddler>>>\n<$set name=\"tv-wikilinks\" value=\"no\">\n<$transclude tiddler=\"$buttonTemplate$\" mode=\"inline\">\n<$transclude tiddler=<<currentTab>> field=\"caption\">\n<$macrocall $name=\"currentTab\" $type=\"text/plain\" $output=\"text/plain\"/>\n</$transclude>\n</$transclude>\n</$set></$tiddler></$button></$tiddler></$set></$list>\n</div>\n<div class=\"tc-tab-divider $class$\"/>\n<div class=\"tc-tab-content $class$\">\n<$list filter=\"$tabsList$\" variable=\"currentTab\">\n\n<$reveal type=\"match\" state=<<qualify \"$state$\">> text=<<currentTab>> default=\"$default$\" retain=\"\"\"$retain$\"\"\">\n\n<$transclude tiddler=\"$template$\" mode=\"block\">\n\n<$transclude tiddler=<<currentTab>> mode=\"block\"/>\n\n</$transclude>\n\n</$reveal>\n\n</$list>\n</div>\n</div>\n\\end\n"
},
"$:/core/macros/tag-picker": {
"title": "$:/core/macros/tag-picker",
"tags": "$:/tags/Macro",
"text": "\\define add-tag-actions()\n<$action-sendmessage $message=\"tm-add-tag\" $param={{$:/temp/NewTagName}}/>\n<$action-deletetiddler $tiddler=\"$:/temp/NewTagName\"/>\n\\end\n\n\\define add-tag-actions()\n<$action-sendmessage $message=\"tm-add-tag\" $param={{$:/temp/NewTagName}}/>\n<$action-deletetiddler $tiddler=\"$:/temp/NewTagName\"/>\n\\end\n\n\\define tag-button()\n<$button class=\"tc-btn-invisible\" tag=\"a\">\n$(actions)$\n<$action-deletetiddler $tiddler=\"$:/temp/NewTagName\"/>\n<$macrocall $name=\"tag-pill\" tag=<<tag>>/>\n</$button>\n\\end\n\n\\define tag-picker(actions)\n<$set name=\"actions\" value=\"\"\"$actions$\"\"\">\n<div class=\"tc-edit-add-tag\">\n<span class=\"tc-add-tag-name\">\n<$keyboard key=\"ENTER\" actions=<<add-tag-actions>>>\n<$edit-text tiddler=\"$:/temp/NewTagName\" tag=\"input\" default=\"\" placeholder={{$:/language/EditTemplate/Tags/Add/Placeholder}} focusPopup=<<qualify \"$:/state/popup/tags-auto-complete\">> class=\"tc-edit-texteditor tc-popup-handle\"/>\n</$keyboard>\n</span> <$button popup=<<qualify \"$:/state/popup/tags-auto-complete\">> class=\"tc-btn-invisible\" tooltip={{$:/language/EditTemplate/Tags/Dropdown/Hint}} aria-label={{$:/language/EditTemplate/Tags/Dropdown/Caption}}>{{$:/core/images/down-arrow}}</$button> <span class=\"tc-add-tag-button\">\n<$set name=\"tag\" value={{$:/temp/NewTagName}}>\n<$button set=\"$:/temp/NewTagName\" setTo=\"\" class=\"\">\n$actions$\n<$action-deletetiddler $tiddler=\"$:/temp/NewTagName\"/>\n{{$:/language/EditTemplate/Tags/Add/Button}}\n</$button>\n</$set>\n</span>\n</div>\n<div class=\"tc-block-dropdown-wrapper\">\n<$reveal state=<<qualify \"$:/state/popup/tags-auto-complete\">> type=\"nomatch\" text=\"\" default=\"\">\n<div class=\"tc-block-dropdown\">\n<$list filter=\"[{$:/temp/NewTagName}minlength{$:/config/Tags/MinLength}limit[1]]\" emptyMessage=\"\"\"<div class=\"tc-search-results\">{{$:/language/Search/Search/TooShort}}</div>\"\"\" variable=\"listItem\">\n<$list filter=\"[tags[]!is[system]search:title{$:/temp/NewTagName}sort[]]\" variable=\"tag\">\n<<tag-button>>\n</$list></$list>\n<hr>\n<$list filter=\"[{$:/temp/NewTagName}minlength{$:/config/Tags/MinLength}limit[1]]\" emptyMessage=\"\"\"<div class=\"tc-search-results\">{{$:/language/Search/Search/TooShort}}</div>\"\"\" variable=\"listItem\">\n<$list filter=\"[tags[]is[system]search:title{$:/temp/NewTagName}sort[]]\" variable=\"tag\">\n<<tag-button>>\n</$list></$list>\n</div>\n</$reveal>\n</div>\n</$set>\n\\end\n"
},
"$:/core/macros/tag": {
"title": "$:/core/macros/tag",
"tags": "$:/tags/Macro",
"text": "\\define tag-pill-styles()\nbackground-color:$(backgroundColor)$;\nfill:$(foregroundColor)$;\ncolor:$(foregroundColor)$;\n\\end\n\n\\define tag-pill-inner(tag,icon,colour,fallbackTarget,colourA,colourB,element-tag,element-attributes,actions)\n<$vars foregroundColor=<<contrastcolour target:\"\"\"$colour$\"\"\" fallbackTarget:\"\"\"$fallbackTarget$\"\"\" colourA:\"\"\"$colourA$\"\"\" colourB:\"\"\"$colourB$\"\"\">> backgroundColor=\"\"\"$colour$\"\"\">\n<$element-tag$ $element-attributes$ class=\"tc-tag-label tc-btn-invisible\" style=<<tag-pill-styles>>>\n$actions$<$transclude tiddler=\"\"\"$icon$\"\"\"/> <$view tiddler=<<__tag__>> field=\"title\" format=\"text\" />\n</$element-tag$>\n</$vars>\n\\end\n\n\\define tag-pill-body(tag,icon,colour,palette,element-tag,element-attributes,actions)\n<$macrocall $name=\"tag-pill-inner\" tag=<<__tag__>> icon=\"\"\"$icon$\"\"\" colour=\"\"\"$colour$\"\"\" fallbackTarget={{$palette$##tag-background}} colourA={{$palette$##foreground}} colourB={{$palette$##background}} element-tag=\"\"\"$element-tag$\"\"\" element-attributes=\"\"\"$element-attributes$\"\"\" actions=\"\"\"$actions$\"\"\"/>\n\\end\n\n\\define tag-pill(tag,element-tag:\"span\",element-attributes:\"\",actions:\"\")\n<span class=\"tc-tag-list-item\">\n<$macrocall $name=\"tag-pill-body\" tag=<<__tag__>> icon={{{ [<__tag__>get[icon]] }}} colour={{{ [<__tag__>get[color]] }}} palette={{$:/palette}} element-tag=\"\"\"$element-tag$\"\"\" element-attributes=\"\"\"$element-attributes$\"\"\" actions=\"\"\"$actions$\"\"\"/>\n</span>\n\\end\n\n\\define tag(tag)\n{{$tag$||$:/core/ui/TagTemplate}}\n\\end\n"
},
"$:/core/macros/thumbnails": {
"title": "$:/core/macros/thumbnails",
"tags": "$:/tags/Macro",
"text": "\\define thumbnail(link,icon,color,background-color,image,caption,width:\"280\",height:\"157\")\n<$link to=\"\"\"$link$\"\"\"><div class=\"tc-thumbnail-wrapper\">\n<div class=\"tc-thumbnail-image\" style=\"width:$width$px;height:$height$px;\"><$reveal type=\"nomatch\" text=\"\" default=\"\"\"$image$\"\"\" tag=\"div\" style=\"width:$width$px;height:$height$px;\">\n[img[$image$]]\n</$reveal><$reveal type=\"match\" text=\"\" default=\"\"\"$image$\"\"\" tag=\"div\" class=\"tc-thumbnail-background\" style=\"width:$width$px;height:$height$px;background-color:$background-color$;\"></$reveal></div><div class=\"tc-thumbnail-icon\" style=\"fill:$color$;color:$color$;\">\n$icon$\n</div><div class=\"tc-thumbnail-caption\">\n$caption$\n</div>\n</div></$link>\n\\end\n\n\\define thumbnail-right(link,icon,color,background-color,image,caption,width:\"280\",height:\"157\")\n<div class=\"tc-thumbnail-right-wrapper\"><<thumbnail \"\"\"$link$\"\"\" \"\"\"$icon$\"\"\" \"\"\"$color$\"\"\" \"\"\"$background-color$\"\"\" \"\"\"$image$\"\"\" \"\"\"$caption$\"\"\" \"\"\"$width$\"\"\" \"\"\"$height$\"\"\">></div>\n\\end\n\n\\define list-thumbnails(filter,width:\"280\",height:\"157\")\n<$list filter=\"\"\"$filter$\"\"\"><$macrocall $name=\"thumbnail\" link={{!!link}} icon={{!!icon}} color={{!!color}} background-color={{!!background-color}} image={{!!image}} caption={{!!caption}} width=\"\"\"$width$\"\"\" height=\"\"\"$height$\"\"\"/></$list>\n\\end\n"
},
"$:/core/macros/timeline": {
"title": "$:/core/macros/timeline",
"created": "20141212105914482",
"modified": "20141212110330815",
"tags": "$:/tags/Macro",
"text": "\\define timeline-title()\n<!-- Override this macro with a global macro \n of the same name if you need to change \n how titles are displayed on the timeline \n -->\n<$view field=\"title\"/>\n\\end\n\\define timeline(limit:\"100\",format:\"DDth MMM YYYY\",subfilter:\"\",dateField:\"modified\")\n<div class=\"tc-timeline\">\n<$list filter=\"[!is[system]$subfilter$has[$dateField$]!sort[$dateField$]limit[$limit$]eachday[$dateField$]]\">\n<div class=\"tc-menu-list-item\">\n<$view field=\"$dateField$\" format=\"date\" template=\"$format$\"/>\n<$list filter=\"[sameday:$dateField${!!$dateField$}!is[system]$subfilter$!sort[$dateField$]]\">\n<div class=\"tc-menu-list-subitem\">\n<$link to={{!!title}}>\n<<timeline-title>>\n</$link>\n</div>\n</$list>\n</div>\n</$list>\n</div>\n\\end\n"
},
"$:/core/macros/toc": {
"title": "$:/core/macros/toc",
"tags": "$:/tags/Macro",
"text": "\\define toc-caption()\n<$set name=\"tv-wikilinks\" value=\"no\">\n <$transclude field=\"caption\">\n <$view field=\"title\"/>\n </$transclude>\n</$set>\n\\end\n\n\\define toc-body(tag,sort:\"\",itemClassFilter,exclude,path)\n<ol class=\"tc-toc\">\n <$list filter=\"\"\"[all[shadows+tiddlers]tag<__tag__>!has[draft.of]$sort$] -[<__tag__>] -[enlist<__exclude__>]\"\"\">\n <$vars item=<<currentTiddler>> path={{{ [<__path__>addsuffix[/]addsuffix<__tag__>] }}} excluded=\"\"\"[enlist<__exclude__>] -[<__tag__>]\"\"\">\n <$set name=\"toc-item-class\" filter=<<__itemClassFilter__>> emptyValue=\"toc-item\" value=\"toc-item-selected\">\n <li class=<<toc-item-class>>>\n <$list filter=\"[all[current]toc-link[no]]\" emptyMessage=\"<$link><$view field='caption'><$view field='title'/></$view></$link>\">\n <<toc-caption>>\n </$list>\n <$macrocall $name=\"toc-body\" tag=<<item>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> exclude=<<excluded>> path=<<path>>/>\n </li>\n </$set>\n </$vars>\n </$list>\n</ol>\n\\end\n\n\\define toc(tag,sort:\"\",itemClassFilter:\" \")\n<$macrocall $name=\"toc-body\" tag=<<__tag__>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> />\n\\end\n\n\\define toc-linked-expandable-body(tag,sort:\"\",itemClassFilter,exclude,path)\n<!-- helper function -->\n<$qualify name=\"toc-state\" title={{{ [[$:/state/toc]addsuffix<__path__>addsuffix[-]addsuffix<currentTiddler>] }}}>\n <$set name=\"toc-item-class\" filter=<<__itemClassFilter__>> emptyValue=\"toc-item\" value=\"toc-item-selected\">\n <li class=<<toc-item-class>>>\n <$link>\n <$reveal type=\"nomatch\" stateTitle=<<toc-state>> text=\"open\">\n <$button setTitle=<<toc-state>> setTo=\"open\" class=\"tc-btn-invisible tc-popup-keep\">\n {{$:/core/images/right-arrow}}\n </$button>\n </$reveal>\n <$reveal type=\"match\" stateTitle=<<toc-state>> text=\"open\">\n <$button setTitle=<<toc-state>> setTo=\"close\" class=\"tc-btn-invisible tc-popup-keep\">\n {{$:/core/images/down-arrow}}\n </$button>\n </$reveal>\n <<toc-caption>>\n </$link>\n <$reveal type=\"match\" stateTitle=<<toc-state>> text=\"open\">\n <$macrocall $name=\"toc-expandable\" tag=<<currentTiddler>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> exclude=<<__exclude__>> path=<<__path__>>/>\n </$reveal>\n </li>\n </$set>\n</$qualify>\n\\end\n\n\\define toc-unlinked-expandable-body(tag,sort:\"\",itemClassFilter:\" \",exclude,path)\n<!-- helper function -->\n<$qualify name=\"toc-state\" title={{{ [[$:/state/toc]addsuffix<__path__>addsuffix[-]addsuffix<currentTiddler>] }}}>\n <$set name=\"toc-item-class\" filter=<<__itemClassFilter__>> emptyValue=\"toc-item\" value=\"toc-item-selected\">\n <li class=<<toc-item-class>>>\n <$reveal type=\"nomatch\" stateTitle=<<toc-state>> text=\"open\">\n <$button setTitle=<<toc-state>> setTo=\"open\" class=\"tc-btn-invisible tc-popup-keep\">\n {{$:/core/images/right-arrow}}\n <<toc-caption>>\n </$button>\n </$reveal>\n <$reveal type=\"match\" stateTitle=<<toc-state>> text=\"open\">\n <$button setTitle=<<toc-state>> setTo=\"close\" class=\"tc-btn-invisible tc-popup-keep\">\n {{$:/core/images/down-arrow}}\n <<toc-caption>>\n </$button>\n </$reveal>\n <$reveal type=\"match\" stateTitle=<<toc-state>> text=\"open\">\n <$macrocall $name=\"toc-expandable\" tag=<<currentTiddler>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> exclude=<<__exclude__>> path=<<__path__>>/>\n </$reveal>\n </li>\n </$set>\n</$qualify>\n\\end\n\n\\define toc-expandable-empty-message()\n<$macrocall $name=\"toc-linked-expandable-body\" tag=<<tag>> sort=<<sort>> itemClassFilter=<<itemClassFilter>> exclude=<<excluded>> path=<<path>>/>\n\\end\n\n\\define toc-expandable(tag,sort:\"\",itemClassFilter:\" \",exclude,path)\n<$vars tag=<<__tag__>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> excluded=\"\"\"[enlist<__exclude__>] -[<__tag__>]\"\"\" path={{{ [<__path__>addsuffix[/]addsuffix<__tag__>] }}}>\n <ol class=\"tc-toc toc-expandable\">\n <$list filter=\"\"\"[all[shadows+tiddlers]tag<__tag__>!has[draft.of]$sort$] -[<__tag__>] -[enlist<__exclude__>]\"\"\">\n <$list filter=\"[all[current]toc-link[no]]\" emptyMessage=<<toc-expandable-empty-message>> >\n <$macrocall $name=\"toc-unlinked-expandable-body\" tag=<<__tag__>> sort=<<__sort__>> itemClassFilter=\"\"\"itemClassFilter\"\"\" exclude=<<excluded>> path=<<path>> />\n </$list>\n </$list>\n </ol>\n</$vars>\n\\end\n\n\\define toc-linked-selective-expandable-body(tag,sort:\"\",itemClassFilter:\" \",exclude,path)\n<$qualify name=\"toc-state\" title={{{ [[$:/state/toc]addsuffix<__path__>addsuffix[-]addsuffix<currentTiddler>] }}}>\n <$set name=\"toc-item-class\" filter=<<__itemClassFilter__>> emptyValue=\"toc-item\" value=\"toc-item-selected\" >\n <li class=<<toc-item-class>>>\n <$link>\n <$list filter=\"[all[current]tagging[]limit[1]]\" variable=\"ignore\" emptyMessage=\"<$button class='tc-btn-invisible'>{{$:/core/images/blank}}</$button>\">\n <$reveal type=\"nomatch\" stateTitle=<<toc-state>> text=\"open\">\n <$button setTitle=<<toc-state>> setTo=\"open\" class=\"tc-btn-invisible tc-popup-keep\">\n {{$:/core/images/right-arrow}}\n </$button>\n </$reveal>\n <$reveal type=\"match\" stateTitle=<<toc-state>> text=\"open\">\n <$button setTitle=<<toc-state>> setTo=\"close\" class=\"tc-btn-invisible tc-popup-keep\">\n {{$:/core/images/down-arrow}}\n </$button>\n </$reveal>\n </$list>\n <<toc-caption>>\n </$link>\n <$reveal type=\"match\" stateTitle=<<toc-state>> text=\"open\">\n <$macrocall $name=\"toc-selective-expandable\" tag=<<currentTiddler>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> exclude=<<__exclude__>> path=<<__path__>>/>\n </$reveal>\n </li>\n </$set>\n</$qualify>\n\\end\n\n\\define toc-unlinked-selective-expandable-body(tag,sort:\"\",itemClassFilter:\" \",exclude,path)\n<$qualify name=\"toc-state\" title={{{ [[$:/state/toc]addsuffix<__path__>addsuffix[-]addsuffix<currentTiddler>] }}}>\n <$set name=\"toc-item-class\" filter=<<__itemClassFilter__>> emptyValue=\"toc-item\" value=\"toc-item-selected\">\n <li class=<<toc-item-class>>>\n <$list filter=\"[all[current]tagging[]limit[1]]\" variable=\"ignore\" emptyMessage=\"<$button class='tc-btn-invisible'>{{$:/core/images/blank}}</$button> <$view field='caption'><$view field='title'/></$view>\">\n <$reveal type=\"nomatch\" stateTitle=<<toc-state>> text=\"open\">\n <$button setTitle=<<toc-state>> setTo=\"open\" class=\"tc-btn-invisible tc-popup-keep\">\n {{$:/core/images/right-arrow}}\n <<toc-caption>>\n </$button>\n </$reveal>\n <$reveal type=\"match\" stateTitle=<<toc-state>> text=\"open\">\n <$button setTitle=<<toc-state>> setTo=\"close\" class=\"tc-btn-invisible tc-popup-keep\">\n {{$:/core/images/down-arrow}}\n <<toc-caption>>\n </$button>\n </$reveal>\n </$list>\n <$reveal type=\"match\" stateTitle=<<toc-state>> text=\"open\">\n <$macrocall $name=\"toc-selective-expandable\" tag=<<currentTiddler>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> exclude=<<__exclude__>> path=<<__path__>>/>\n </$reveal>\n </li>\n </$set>\n</$qualify>\n\\end\n\n\\define toc-selective-expandable-empty-message()\n<$macrocall $name=\"toc-linked-selective-expandable-body\" tag=<<tag>> sort=<<sort>> itemClassFilter=<<itemClassFilter>> exclude=<<excluded>> path=<<path>>/>\n\\end\n\n\\define toc-selective-expandable(tag,sort:\"\",itemClassFilter,exclude,path)\n<$vars tag=<<__tag__>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> excluded=\"\"\"[enlist<__exclude__>] -[<__tag__>]\"\"\" path={{{ [<__path__>addsuffix[/]addsuffix<__tag__>] }}}>\n <ol class=\"tc-toc toc-selective-expandable\">\n <$list filter=\"\"\"[all[shadows+tiddlers]tag<__tag__>!has[draft.of]$sort$] -[<__tag__>] -[enlist<__exclude__>]\"\"\">\n <$list filter=\"[all[current]toc-link[no]]\" variable=\"ignore\" emptyMessage=<<toc-selective-expandable-empty-message>> >\n <$macrocall $name=\"toc-unlinked-selective-expandable-body\" tag=<<__tag__>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> exclude=<<excluded>> path=<<path>>/>\n </$list>\n </$list>\n </ol>\n</$vars>\n\\end\n\n\\define toc-tabbed-external-nav(tag,sort:\"\",selectedTiddler:\"$:/temp/toc/selectedTiddler\",unselectedText,missingText,template:\"\")\n<$tiddler tiddler={{{ [<__selectedTiddler__>get[text]] }}}>\n <div class=\"tc-tabbed-table-of-contents\">\n <$linkcatcher to=<<__selectedTiddler__>>>\n <div class=\"tc-table-of-contents\">\n <$macrocall $name=\"toc-selective-expandable\" tag=<<__tag__>> sort=<<__sort__>> itemClassFilter=\"[all[current]field:title<__selectedTiddler__>]\"/>\n </div>\n </$linkcatcher>\n <div class=\"tc-tabbed-table-of-contents-content\">\n <$reveal stateTitle=<<__selectedTiddler__>> type=\"nomatch\" text=\"\">\n <$transclude mode=\"block\" tiddler=<<__template__>>>\n <h1><<toc-caption>></h1>\n <$transclude mode=\"block\">$missingText$</$transclude>\n </$transclude>\n </$reveal>\n <$reveal stateTitle=<<__selectedTiddler__>> type=\"match\" text=\"\">\n $unselectedText$\n </$reveal>\n </div>\n </div>\n</$tiddler>\n\\end\n\n\\define toc-tabbed-internal-nav(tag,sort:\"\",selectedTiddler:\"$:/temp/toc/selectedTiddler\",unselectedText,missingText,template:\"\")\n<$linkcatcher to=<<__selectedTiddler__>>>\n <$macrocall $name=\"toc-tabbed-external-nav\" tag=<<__tag__>> sort=<<__sort__>> selectedTiddler=<<__selectedTiddler__>> unselectedText=<<__unselectedText__>> missingText=<<__missingText__>> template=<<__template__>>/>\n</$linkcatcher>\n\\end\n\n"
},
"$:/core/macros/translink": {
"title": "$:/core/macros/translink",
"tags": "$:/tags/Macro",
"text": "\\define translink(title,mode:\"block\")\n<div style=\"border:1px solid #ccc; padding: 0.5em; background: black; foreground; white;\">\n<$link to=\"\"\"$title$\"\"\">\n<$text text=\"\"\"$title$\"\"\"/>\n</$link>\n<div style=\"border:1px solid #ccc; padding: 0.5em; background: white; foreground; black;\">\n<$transclude tiddler=\"\"\"$title$\"\"\" mode=\"$mode$\">\n\"<$text text=\"\"\"$title$\"\"\"/>\" is missing\n</$transclude>\n</div>\n</div>\n\\end\n"
},
"$:/core/macros/tree": {
"title": "$:/core/macros/tree",
"tags": "$:/tags/Macro",
"text": "\\define leaf-link(full-title, chunk)\n<$link to=<<__full-title__>>><$text text=<<__chunk__>>/></$link>\n\\end\n\n\\define leaf-node(prefix, chunk)\n<li>\n<$list filter=\"[<__prefix__>addsuffix<__chunk__>is[shadow]] [<__prefix__>addsuffix<__chunk__>is[tiddler]]\" variable=\"full-title\">\n<$list filter=\"[<full-title>removeprefix<__prefix__>]\" variable=\"chunk\">\n<span>{{$:/core/images/file}}</span> <$macrocall $name=\"leaf-link\" full-title=<<full-title>> chunk=<<chunk>>/>\n</$list>\n</$list>\n</li>\n\\end\n\n\\define branch-node(prefix, chunk)\n<li>\n<$set name=\"reveal-state\" value={{{ [[$:/state/tree/]addsuffix<__prefix__>addsuffix<__chunk__>] }}}>\n<$reveal type=\"nomatch\" stateTitle=<<reveal-state>> text=\"show\">\n<$button setTitle=<<reveal-state>> setTo=\"show\" class=\"tc-btn-invisible\">\n{{$:/core/images/folder}} <$text text=<<__chunk__>>/>\n</$button>\n</$reveal>\n<$reveal type=\"match\" stateTitle=<<reveal-state>> text=\"show\">\n<$button setTitle=<<reveal-state>> setTo=\"hide\" class=\"tc-btn-invisible\">\n{{$:/core/images/folder}} <$text text=<<__chunk__>>/>\n</$button>\n</$reveal>\n<span>(<$count filter=\"[all[shadows+tiddlers]removeprefix<__prefix__>removeprefix<__chunk__>] -[<__prefix__>addsuffix<__chunk__>]\"/>)</span>\n<$reveal type=\"match\" stateTitle=<<reveal-state>> text=\"show\">\n<$macrocall $name=\"tree-node\" prefix={{{ [<__prefix__>addsuffix<__chunk__>] }}}/>\n</$reveal>\n</$set>\n</li>\n\\end\n\n\\define tree-node(prefix)\n<ol>\n<$list filter=\"[all[shadows+tiddlers]removeprefix<__prefix__>splitbefore[/]sort[]!suffix[/]]\" variable=\"chunk\">\n<$macrocall $name=\"leaf-node\" prefix=<<__prefix__>> chunk=<<chunk>>/>\n</$list>\n<$list filter=\"[all[shadows+tiddlers]removeprefix<__prefix__>splitbefore[/]sort[]suffix[/]]\" variable=\"chunk\">\n<$macrocall $name=\"branch-node\" prefix=<<__prefix__>> chunk=<<chunk>>/>\n</$list>\n</ol>\n\\end\n\n\\define tree(prefix: \"$:/\")\n<div class=\"tc-tree\">\n<span><$text text=<<__prefix__>>/></span>\n<div>\n<$macrocall $name=\"tree-node\" prefix=<<__prefix__>>/>\n</div>\n</div>\n\\end\n"
},
"$:/snippets/minilanguageswitcher": {
"title": "$:/snippets/minilanguageswitcher",
"text": "<$select tiddler=\"$:/language\">\n<$list filter=\"[[$:/languages/en-GB]] [plugin-type[language]sort[title]]\">\n<option value=<<currentTiddler>>><$view field=\"description\"><$view field=\"name\"><$view field=\"title\"/></$view></$view></option>\n</$list>\n</$select>"
},
"$:/snippets/minithemeswitcher": {
"title": "$:/snippets/minithemeswitcher",
"text": "\\define lingo-base() $:/language/ControlPanel/Theme/\n<<lingo Prompt>> <$select tiddler=\"$:/theme\">\n<$list filter=\"[plugin-type[theme]sort[title]]\">\n<option value=<<currentTiddler>>><$view field=\"name\"><$view field=\"title\"/></$view></option>\n</$list>\n</$select>"
},
"$:/snippets/modules": {
"title": "$:/snippets/modules",
"text": "\\define describeModuleType(type)\n{{$:/language/Docs/ModuleTypes/$type$}}\n\\end\n<$list filter=\"[moduletypes[]]\">\n\n!! <$macrocall $name=\"currentTiddler\" $type=\"text/plain\" $output=\"text/plain\"/>\n\n<$macrocall $name=\"describeModuleType\" type=<<currentTiddler>>/>\n\n<ul><$list filter=\"[all[current]modules[]]\"><li><$link><<currentTiddler>></$link>\n</li>\n</$list>\n</ul>\n</$list>\n"
},
"$:/palette": {
"title": "$:/palette",
"text": "$:/palettes/Vanilla"
},
"$:/snippets/paletteeditor": {
"title": "$:/snippets/paletteeditor",
"text": "\\define lingo-base() $:/language/ControlPanel/Palette/Editor/\n\\define describePaletteColour(colour)\n<$transclude tiddler=\"$:/language/Docs/PaletteColours/$colour$\"><$text text=\"$colour$\"/></$transclude>\n\\end\n<$set name=\"currentTiddler\" value={{$:/palette}}>\n\n<<lingo Prompt>> <$link to={{$:/palette}}><$macrocall $name=\"currentTiddler\" $output=\"text/plain\"/></$link>\n\n<$list filter=\"[all[current]is[shadow]is[tiddler]]\" variable=\"listItem\">\n<<lingo Prompt/Modified>>\n<$button message=\"tm-delete-tiddler\" param={{$:/palette}}><<lingo Reset/Caption>></$button>\n</$list>\n\n<$list filter=\"[all[current]is[shadow]!is[tiddler]]\" variable=\"listItem\">\n<<lingo Clone/Prompt>>\n</$list>\n\n<$button message=\"tm-new-tiddler\" param={{$:/palette}}><<lingo Clone/Caption>></$button>\n\n<table>\n<tbody>\n<$list filter=\"[all[current]indexes[]]\" variable=\"colourName\">\n<tr>\n<td>\n''<$macrocall $name=\"describePaletteColour\" colour=<<colourName>>/>''<br/>\n<$macrocall $name=\"colourName\" $output=\"text/plain\"/>\n</td>\n<td>\n<$edit-text index=<<colourName>> tag=\"input\"/>\n<br>\n<$edit-text index=<<colourName>> type=\"color\" tag=\"input\"/>\n</td>\n</tr>\n</$list>\n</tbody>\n</table>\n</$set>\n"
},
"$:/snippets/palettepreview": {
"title": "$:/snippets/palettepreview",
"text": "<$set name=\"currentTiddler\" value={{$:/palette}}>\n{{||$:/snippets/currpalettepreview}}\n</$set>\n"
},
"$:/snippets/paletteswitcher": {
"title": "$:/snippets/paletteswitcher",
"text": "<$linkcatcher to=\"$:/palette\">\n<div class=\"tc-chooser\"><$list filter=\"[all[shadows+tiddlers]tag[$:/tags/Palette]sort[description]]\"><$set name=\"cls\" filter=\"[all[current]prefix{$:/palette}]\" value=\"tc-chooser-item tc-chosen\" emptyValue=\"tc-chooser-item\"><div class=<<cls>>><$link to={{!!title}}>''<$view field=\"name\" format=\"text\"/>'' - <$view field=\"description\" format=\"text\"/>{{||$:/snippets/currpalettepreview}}</$link>\n</div></$set>\n</$list>\n</div>\n</$linkcatcher>"
},
"$:/snippets/peek-stylesheets": {
"title": "$:/snippets/peek-stylesheets",
"text": "\\define expandable-stylesheets-list()\n<ol>\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/Stylesheet]!has[draft.of]]\">\n<$vars state=<<qualify \"$:/config/peek-stylesheets/open/\">>>\n<$set name=\"state\" value={{{ [<state>addsuffix<currentTiddler>] }}}>\n<li>\n<$reveal type=\"match\" state=<<state>> text=\"yes\" tag=\"span\">\n<$button set=<<state>> setTo=\"no\" class=\"tc-btn-invisible\">\n{{$:/core/images/down-arrow}}\n</$button>\n</$reveal>\n<$reveal type=\"nomatch\" state=<<state>> text=\"yes\" tag=\"span\">\n<$button set=<<state>> setTo=\"yes\" class=\"tc-btn-invisible\">\n{{$:/core/images/right-arrow}}\n</$button>\n</$reveal>\n<$link>\n<$view field=\"title\"/>\n</$link>\n<$reveal type=\"match\" state=<<state>> text=\"yes\" tag=\"div\">\n<$set name=\"source\" tiddler=<<currentTiddler>>>\n<$wikify name=\"styles\" text=<<source>>>\n<pre>\n<code>\n<$text text=<<styles>>/>\n</code>\n</pre>\n</$wikify>\n</$set>\n</$reveal>\n</li>\n</$set>\n</$vars>\n</$list>\n</ol>\n\\end\n\n\\define stylesheets-list()\n<ol>\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/Stylesheet]!has[draft.of]]\">\n<li>\n<$link>\n<$view field=\"title\"/>\n</$link>\n<$set name=\"source\" tiddler=<<currentTiddler>>>\n<$wikify name=\"styles\" text=<<source>>>\n<pre>\n<code>\n<$text text=<<styles>>/>\n</code>\n</pre>\n</$wikify>\n</$set>\n</li>\n</$list>\n</ol>\n\\end\n\n<$vars modeState=<<qualify \"$:/config/peek-stylesheets/mode/\">>>\n\n<$reveal type=\"nomatch\" state=<<modeState>> text=\"expanded\" tag=\"div\">\n<$button set=<<modeState>> setTo=\"expanded\" class=\"tc-btn-invisible\">{{$:/core/images/chevron-right}} {{$:/language/ControlPanel/Stylesheets/Expand/Caption}}</$button>\n</$reveal>\n<$reveal type=\"match\" state=<<modeState>> text=\"expanded\" tag=\"div\">\n<$button set=<<modeState>> setTo=\"restored\" class=\"tc-btn-invisible\">{{$:/core/images/chevron-down}} {{$:/language/ControlPanel/Stylesheets/Restore/Caption}}</$button>\n</$reveal>\n\n<$reveal type=\"nomatch\" state=<<modeState>> text=\"expanded\" tag=\"div\">\n<<expandable-stylesheets-list>>\n</$reveal>\n<$reveal type=\"match\" state=<<modeState>> text=\"expanded\" tag=\"div\">\n<<stylesheets-list>>\n</$reveal>\n\n</$vars>\n"
},
"$:/temp/search": {
"title": "$:/temp/search",
"text": ""
},
"$:/tags/AdvancedSearch": {
"title": "$:/tags/AdvancedSearch",
"list": "[[$:/core/ui/AdvancedSearch/Standard]] [[$:/core/ui/AdvancedSearch/System]] [[$:/core/ui/AdvancedSearch/Shadows]] [[$:/core/ui/AdvancedSearch/Filter]]"
},
"$:/tags/AdvancedSearch/FilterButton": {
"title": "$:/tags/AdvancedSearch/FilterButton",
"list": "$:/core/ui/AdvancedSearch/Filter/FilterButtons/dropdown $:/core/ui/AdvancedSearch/Filter/FilterButtons/clear $:/core/ui/AdvancedSearch/Filter/FilterButtons/export $:/core/ui/AdvancedSearch/Filter/FilterButtons/delete"
},
"$:/tags/ControlPanel": {
"title": "$:/tags/ControlPanel",
"list": "$:/core/ui/ControlPanel/Info $:/core/ui/ControlPanel/Appearance $:/core/ui/ControlPanel/Settings $:/core/ui/ControlPanel/Saving $:/core/ui/ControlPanel/Plugins $:/core/ui/ControlPanel/Tools $:/core/ui/ControlPanel/Internals"
},
"$:/tags/ControlPanel/Info": {
"title": "$:/tags/ControlPanel/Info",
"list": "$:/core/ui/ControlPanel/Basics $:/core/ui/ControlPanel/Advanced"
},
"$:/tags/ControlPanel/Plugins": {
"title": "$:/tags/ControlPanel/Plugins",
"list": "[[$:/core/ui/ControlPanel/Plugins/Installed]] [[$:/core/ui/ControlPanel/Plugins/Add]]"
},
"$:/tags/EditTemplate": {
"title": "$:/tags/EditTemplate",
"list": "[[$:/core/ui/EditTemplate/controls]] [[$:/core/ui/EditTemplate/title]] [[$:/core/ui/EditTemplate/tags]] [[$:/core/ui/EditTemplate/shadow]] [[$:/core/ui/ViewTemplate/classic]] [[$:/core/ui/EditTemplate/body]] [[$:/core/ui/EditTemplate/type]] [[$:/core/ui/EditTemplate/fields]]"
},
"$:/tags/EditToolbar": {
"title": "$:/tags/EditToolbar",
"list": "[[$:/core/ui/Buttons/delete]] [[$:/core/ui/Buttons/cancel]] [[$:/core/ui/Buttons/save]]"
},
"$:/tags/EditorToolbar": {
"title": "$:/tags/EditorToolbar",
"list": "$:/core/ui/EditorToolbar/paint $:/core/ui/EditorToolbar/opacity $:/core/ui/EditorToolbar/line-width $:/core/ui/EditorToolbar/rotate-left $:/core/ui/EditorToolbar/clear $:/core/ui/EditorToolbar/bold $:/core/ui/EditorToolbar/italic $:/core/ui/EditorToolbar/strikethrough $:/core/ui/EditorToolbar/underline $:/core/ui/EditorToolbar/superscript $:/core/ui/EditorToolbar/subscript $:/core/ui/EditorToolbar/mono-line $:/core/ui/EditorToolbar/mono-block $:/core/ui/EditorToolbar/quote $:/core/ui/EditorToolbar/list-bullet $:/core/ui/EditorToolbar/list-number $:/core/ui/EditorToolbar/heading-1 $:/core/ui/EditorToolbar/heading-2 $:/core/ui/EditorToolbar/heading-3 $:/core/ui/EditorToolbar/heading-4 $:/core/ui/EditorToolbar/heading-5 $:/core/ui/EditorToolbar/heading-6 $:/core/ui/EditorToolbar/link $:/core/ui/EditorToolbar/excise $:/core/ui/EditorToolbar/picture $:/core/ui/EditorToolbar/stamp $:/core/ui/EditorToolbar/size $:/core/ui/EditorToolbar/editor-height $:/core/ui/EditorToolbar/more $:/core/ui/EditorToolbar/preview $:/core/ui/EditorToolbar/preview-type"
},
"$:/tags/Manager/ItemMain": {
"title": "$:/tags/Manager/ItemMain",
"list": "$:/Manager/ItemMain/WikifiedText $:/Manager/ItemMain/RawText $:/Manager/ItemMain/Fields"
},
"$:/tags/Manager/ItemSidebar": {
"title": "$:/tags/Manager/ItemSidebar",
"list": "$:/Manager/ItemSidebar/Tags $:/Manager/ItemSidebar/Colour $:/Manager/ItemSidebar/Icon $:/Manager/ItemSidebar/Tools"
},
"$:/tags/MoreSideBar": {
"title": "$:/tags/MoreSideBar",
"list": "[[$:/core/ui/MoreSideBar/All]] [[$:/core/ui/MoreSideBar/Recent]] [[$:/core/ui/MoreSideBar/Tags]] [[$:/core/ui/MoreSideBar/Missing]] [[$:/core/ui/MoreSideBar/Drafts]] [[$:/core/ui/MoreSideBar/Orphans]] [[$:/core/ui/MoreSideBar/Types]] [[$:/core/ui/MoreSideBar/System]] [[$:/core/ui/MoreSideBar/Shadows]] [[$:/core/ui/MoreSideBar/Explorer]] [[$:/core/ui/MoreSideBar/Plugins]]",
"text": ""
},
"$:/tags/PageControls": {
"title": "$:/tags/PageControls",
"list": "[[$:/core/ui/Buttons/home]] [[$:/core/ui/Buttons/close-all]] [[$:/core/ui/Buttons/fold-all]] [[$:/core/ui/Buttons/unfold-all]] [[$:/core/ui/Buttons/permaview]] [[$:/core/ui/Buttons/new-tiddler]] [[$:/core/ui/Buttons/new-journal]] [[$:/core/ui/Buttons/new-image]] [[$:/core/ui/Buttons/import]] [[$:/core/ui/Buttons/export-page]] [[$:/core/ui/Buttons/control-panel]] [[$:/core/ui/Buttons/advanced-search]] [[$:/core/ui/Buttons/manager]] [[$:/core/ui/Buttons/tag-manager]] [[$:/core/ui/Buttons/language]] [[$:/core/ui/Buttons/palette]] [[$:/core/ui/Buttons/theme]] [[$:/core/ui/Buttons/storyview]] [[$:/core/ui/Buttons/encryption]] [[$:/core/ui/Buttons/timestamp]] [[$:/core/ui/Buttons/full-screen]] [[$:/core/ui/Buttons/print]] [[$:/core/ui/Buttons/save-wiki]] [[$:/core/ui/Buttons/refresh]] [[$:/core/ui/Buttons/more-page-actions]]"
},
"$:/tags/PageTemplate": {
"title": "$:/tags/PageTemplate",
"list": "[[$:/core/ui/PageTemplate/topleftbar]] [[$:/core/ui/PageTemplate/toprightbar]] [[$:/core/ui/PageTemplate/sidebar]] [[$:/core/ui/PageTemplate/story]] [[$:/core/ui/PageTemplate/alerts]]",
"text": ""
},
"$:/tags/SideBar": {
"title": "$:/tags/SideBar",
"list": "[[$:/core/ui/SideBar/Open]] [[$:/core/ui/SideBar/Recent]] [[$:/core/ui/SideBar/Tools]] [[$:/core/ui/SideBar/More]]",
"text": ""
},
"$:/tags/SideBarSegment": {
"title": "$:/tags/SideBarSegment",
"list": "[[$:/core/ui/SideBarSegments/site-title]] [[$:/core/ui/SideBarSegments/site-subtitle]] [[$:/core/ui/SideBarSegments/page-controls]] [[$:/core/ui/SideBarSegments/search]] [[$:/core/ui/SideBarSegments/tabs]]"
},
"$:/tags/TiddlerInfo": {
"title": "$:/tags/TiddlerInfo",
"list": "[[$:/core/ui/TiddlerInfo/Tools]] [[$:/core/ui/TiddlerInfo/References]] [[$:/core/ui/TiddlerInfo/Tagging]] [[$:/core/ui/TiddlerInfo/List]] [[$:/core/ui/TiddlerInfo/Listed]] [[$:/core/ui/TiddlerInfo/Fields]]",
"text": ""
},
"$:/tags/TiddlerInfo/Advanced": {
"title": "$:/tags/TiddlerInfo/Advanced",
"list": "[[$:/core/ui/TiddlerInfo/Advanced/ShadowInfo]] [[$:/core/ui/TiddlerInfo/Advanced/PluginInfo]]"
},
"$:/tags/ViewTemplate": {
"title": "$:/tags/ViewTemplate",
"list": "[[$:/core/ui/ViewTemplate/title]] [[$:/core/ui/ViewTemplate/unfold]] [[$:/core/ui/ViewTemplate/subtitle]] [[$:/core/ui/ViewTemplate/tags]] [[$:/core/ui/ViewTemplate/classic]] [[$:/core/ui/ViewTemplate/body]]"
},
"$:/tags/ViewToolbar": {
"title": "$:/tags/ViewToolbar",
"list": "[[$:/core/ui/Buttons/more-tiddler-actions]] [[$:/core/ui/Buttons/info]] [[$:/core/ui/Buttons/new-here]] [[$:/core/ui/Buttons/new-journal-here]] [[$:/core/ui/Buttons/clone]] [[$:/core/ui/Buttons/export-tiddler]] [[$:/core/ui/Buttons/edit]] [[$:/core/ui/Buttons/delete]] [[$:/core/ui/Buttons/permalink]] [[$:/core/ui/Buttons/permaview]] [[$:/core/ui/Buttons/open-window]] [[$:/core/ui/Buttons/close-others]] [[$:/core/ui/Buttons/close]] [[$:/core/ui/Buttons/fold-others]] [[$:/core/ui/Buttons/fold]]"
},
"$:/snippets/themeswitcher": {
"title": "$:/snippets/themeswitcher",
"text": "<$linkcatcher to=\"$:/theme\">\n<div class=\"tc-chooser\"><$list filter=\"[plugin-type[theme]sort[title]]\"><$set name=\"cls\" filter=\"[all[current]field:title{$:/theme}] [[$:/theme]!has[text]addsuffix[s/tiddlywiki/vanilla]field:title<currentTiddler>] +[limit[1]]\" value=\"tc-chooser-item tc-chosen\" emptyValue=\"tc-chooser-item\"><div class=<<cls>>><$link to={{!!title}}>''<$view field=\"name\" format=\"text\"/>'' <$view field=\"description\" format=\"text\"/></$link></div>\n</$set>\n</$list>\n</div>\n</$linkcatcher>"
},
"$:/core/wiki/title": {
"title": "$:/core/wiki/title",
"text": "{{$:/SiteTitle}} --- {{$:/SiteSubtitle}}"
},
"$:/view": {
"title": "$:/view",
"text": "classic"
},
"$:/snippets/viewswitcher": {
"title": "$:/snippets/viewswitcher",
"text": "\\define icon()\n$:/core/images/storyview-$(storyview)$\n\\end\n<$linkcatcher to=\"$:/view\">\n<div class=\"tc-chooser\">\n<$list filter=\"[storyviews[]]\" variable=\"storyview\">\n<$set name=\"cls\" filter=\"[<storyview>prefix{$:/view}]\" value=\"tc-chooser-item tc-chosen\" emptyValue=\"tc-chooser-item\"><div class=<<cls>>>\n<$link to=<<storyview>>>\n<$transclude tiddler=<<icon>>/>\n<$text text=<<storyview>>/>\n</$link>\n</div>\n</$set>\n</$list>\n</div>\n</$linkcatcher>"
}
}
}
Welcome
{
"tiddlers": {
"Untitled": {
"title": "Untitled",
"text": "<<list-links \"[tag[category]]\">>",
"type": "text/plain"
}
}
}
no
lifelong, spiraling discovery and learning
Full-Mindedness and Mind-Fullness
show
yes
$:/core/ui/ControlPanel/Appearance
$:/core/ui/MoreSideBar/All
$:/core/ui/SideBar/More
Haggai Mark
.borderless,
.borderless table,
.borderless td,
.borderless tr,
.borderless th,
.borderless tbody
{ border:0 !important; }
{
"tiddlers": {
"$:/info/browser": {
"title": "$:/info/browser",
"text": "yes"
},
"$:/info/node": {
"title": "$:/info/node",
"text": "no"
},
"$:/info/url/full": {
"title": "$:/info/url/full",
"text": "file:///Users/hmark/Downloads/tiddlywikis/wiki.html"
},
"$:/info/url/host": {
"title": "$:/info/url/host",
"text": ""
},
"$:/info/url/hostname": {
"title": "$:/info/url/hostname",
"text": ""
},
"$:/info/url/protocol": {
"title": "$:/info/url/protocol",
"text": "file:"
},
"$:/info/url/port": {
"title": "$:/info/url/port",
"text": ""
},
"$:/info/url/pathname": {
"title": "$:/info/url/pathname",
"text": "/Users/hmark/Downloads/tiddlywikis/wiki.html"
},
"$:/info/url/search": {
"title": "$:/info/url/search",
"text": ""
},
"$:/info/url/origin": {
"title": "$:/info/url/origin",
"text": "null"
},
"$:/info/browser/screen/width": {
"title": "$:/info/browser/screen/width",
"text": "1680"
},
"$:/info/browser/screen/height": {
"title": "$:/info/browser/screen/height",
"text": "1050"
}
}
}
bret
$:/themes/tiddlywiki/snowwhite
{
"tiddlers": {
"$:/themes/tiddlywiki/snowwhite/base": {
"title": "$:/themes/tiddlywiki/snowwhite/base",
"tags": "[[$:/tags/Stylesheet]]",
"text": "\\rules only filteredtranscludeinline transcludeinline macrodef macrocallinline\n\n.tc-sidebar-header {\n\ttext-shadow: 0 1px 0 <<colour sidebar-foreground-shadow>>;\n}\n\n.tc-tiddler-info {\n\t<<box-shadow \"inset 1px 2px 3px rgba(0,0,0,0.1)\">>\n}\n\n@media screen {\n\t.tc-tiddler-frame {\n\t\t<<box-shadow \"1px 1px 5px rgba(0, 0, 0, 0.3)\">>\n\t}\n}\n\n@media (max-width: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}}) {\n\t.tc-tiddler-frame {\n\t\t<<box-shadow none>>\n\t}\n}\n\n.tc-page-controls button svg, .tc-tiddler-controls button svg, .tc-topbar button svg {\n\t<<transition \"fill 150ms ease-in-out\">>\n}\n\n.tc-tiddler-controls button.tc-selected,\n.tc-page-controls button.tc-selected {\n\t<<filter \"drop-shadow(0px -1px 2px rgba(0,0,0,0.25))\">>\n}\n\n.tc-tiddler-frame input.tc-edit-texteditor {\n\t<<box-shadow \"inset 0 1px 8px rgba(0, 0, 0, 0.15)\">>\n}\n\n.tc-edit-tags {\n\t<<box-shadow \"inset 0 1px 8px rgba(0, 0, 0, 0.15)\">>\n}\n\n.tc-tiddler-frame .tc-edit-tags input.tc-edit-texteditor {\n\t<<box-shadow \"none\">>\n\tborder: none;\n\toutline: none;\n}\n\ntextarea.tc-edit-texteditor {\n\tfont-family: {{$:/themes/tiddlywiki/vanilla/settings/editorfontfamily}};\n}\n\ncanvas.tc-edit-bitmapeditor {\n\t<<box-shadow \"2px 2px 5px rgba(0, 0, 0, 0.5)\">>\n}\n\n.tc-drop-down {\n\tborder-radius: 4px;\n\t<<box-shadow \"2px 2px 10px rgba(0, 0, 0, 0.5)\">>\n}\n\n.tc-block-dropdown {\n\tborder-radius: 4px;\n\t<<box-shadow \"2px 2px 10px rgba(0, 0, 0, 0.5)\">>\n}\n\n.tc-modal {\n\tborder-radius: 6px;\n\t<<box-shadow \"0 3px 7px rgba(0,0,0,0.3)\">>\n}\n\n.tc-modal-footer {\n\tborder-radius: 0 0 6px 6px;\n\t<<box-shadow \"inset 0 1px 0 #fff\">>;\n}\n\n\n.tc-alert {\n\tborder-radius: 6px;\n\t<<box-shadow \"0 3px 7px rgba(0,0,0,0.6)\">>\n}\n\n.tc-notification {\n\tborder-radius: 6px;\n\t<<box-shadow \"0 3px 7px rgba(0,0,0,0.3)\">>\n\ttext-shadow: 0 1px 0 rgba(255,255,255, 0.8);\n}\n\n.tc-sidebar-lists .tc-tab-set .tc-tab-divider {\n\tborder-top: none;\n\theight: 1px;\n\t<<background-linear-gradient \"left, rgba(0,0,0,0.15) 0%, rgba(0,0,0,0.0) 100%\">>\n}\n\n.tc-more-sidebar > .tc-tab-set > .tc-tab-buttons > button {\n\t<<background-linear-gradient \"left, rgba(0,0,0,0.01) 0%, rgba(0,0,0,0.1) 100%\">>\n}\n\n.tc-more-sidebar > .tc-tab-set > .tc-tab-buttons > button.tc-tab-selected {\n\t<<background-linear-gradient \"left, rgba(0,0,0,0.05) 0%, rgba(255,255,255,0.05) 100%\">>\n}\n\n.tc-message-box img {\n\t<<box-shadow \"1px 1px 3px rgba(0,0,0,0.5)\">>\n}\n\n.tc-plugin-info {\n\t<<box-shadow \"1px 1px 3px rgba(0,0,0,0.5)\">>\n}\n"
}
}
}
{
"tiddlers": {
"$:/themes/tiddlywiki/vanilla/themetweaks": {
"title": "$:/themes/tiddlywiki/vanilla/themetweaks",
"tags": "$:/tags/ControlPanel/Appearance",
"caption": "{{$:/language/ThemeTweaks/ThemeTweaks}}",
"text": "\\define lingo-base() $:/language/ThemeTweaks/\n\n\\define replacement-text()\n[img[$(imageTitle)$]]\n\\end\n\n\\define backgroundimage-dropdown()\n<div class=\"tc-drop-down-wrapper\">\n<$button popup=<<qualify \"$:/state/popup/themetweaks/backgroundimage\">> class=\"tc-btn-invisible tc-btn-dropdown\">{{$:/core/images/down-arrow}}</$button>\n<$reveal state=<<qualify \"$:/state/popup/themetweaks/backgroundimage\">> type=\"popup\" position=\"belowleft\" text=\"\" default=\"\">\n<div class=\"tc-drop-down\">\n<$macrocall $name=\"image-picker\" actions=\"\"\"\n\n<$action-setfield\n\t$tiddler=\"$:/themes/tiddlywiki/vanilla/settings/backgroundimage\"\n\t$value=<<imageTitle>>\n/>\n\n\"\"\"/>\n</div>\n</$reveal>\n</div>\n\\end\n\n\\define backgroundimageattachment-dropdown()\n<$select tiddler=\"$:/themes/tiddlywiki/vanilla/settings/backgroundimageattachment\" default=\"scroll\">\n<option value=\"scroll\"><<lingo Settings/BackgroundImageAttachment/Scroll>></option>\n<option value=\"fixed\"><<lingo Settings/BackgroundImageAttachment/Fixed>></option>\n</$select>\n\\end\n\n\\define backgroundimagesize-dropdown()\n<$select tiddler=\"$:/themes/tiddlywiki/vanilla/settings/backgroundimagesize\" default=\"scroll\">\n<option value=\"auto\"><<lingo Settings/BackgroundImageSize/Auto>></option>\n<option value=\"cover\"><<lingo Settings/BackgroundImageSize/Cover>></option>\n<option value=\"contain\"><<lingo Settings/BackgroundImageSize/Contain>></option>\n</$select>\n\\end\n\n<<lingo ThemeTweaks/Hint>>\n\n! <<lingo Options>>\n\n|<$link to=\"$:/themes/tiddlywiki/vanilla/options/sidebarlayout\"><<lingo Options/SidebarLayout>></$link> |<$select tiddler=\"$:/themes/tiddlywiki/vanilla/options/sidebarlayout\"><option value=\"fixed-fluid\"><<lingo Options/SidebarLayout/Fixed-Fluid>></option><option value=\"fluid-fixed\"><<lingo Options/SidebarLayout/Fluid-Fixed>></option></$select> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/options/stickytitles\"><<lingo Options/StickyTitles>></$link><br>//<<lingo Options/StickyTitles/Hint>>// |<$select tiddler=\"$:/themes/tiddlywiki/vanilla/options/stickytitles\"><option value=\"no\">{{$:/language/No}}</option><option value=\"yes\">{{$:/language/Yes}}</option></$select> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/options/codewrapping\"><<lingo Options/CodeWrapping>></$link> |<$select tiddler=\"$:/themes/tiddlywiki/vanilla/options/codewrapping\"><option value=\"pre\">{{$:/language/No}}</option><option value=\"pre-wrap\">{{$:/language/Yes}}</option></$select> |\n\n! <<lingo Settings>>\n\n|<$link to=\"$:/themes/tiddlywiki/vanilla/settings/fontfamily\"><<lingo Settings/FontFamily>></$link> |<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/settings/fontfamily\" default=\"\" tag=\"input\"/> | |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/settings/codefontfamily\"><<lingo Settings/CodeFontFamily>></$link> |<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/settings/codefontfamily\" default=\"\" tag=\"input\"/> | |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/settings/editorfontfamily\"><<lingo Settings/EditorFontFamily>></$link> |<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/settings/editorfontfamily\" default=\"\" tag=\"input\"/> | |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/settings/backgroundimage\"><<lingo Settings/BackgroundImage>></$link> |<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/settings/backgroundimage\" default=\"\" tag=\"input\"/> |<<backgroundimage-dropdown>> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/settings/backgroundimageattachment\"><<lingo Settings/BackgroundImageAttachment>></$link> |<<backgroundimageattachment-dropdown>> | |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/settings/backgroundimagesize\"><<lingo Settings/BackgroundImageSize>></$link> |<<backgroundimagesize-dropdown>> | |\n\n! <<lingo Metrics>>\n\n|<$link to=\"$:/themes/tiddlywiki/vanilla/metrics/fontsize\"><<lingo Metrics/FontSize>></$link> |<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/metrics/fontsize\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/metrics/lineheight\"><<lingo Metrics/LineHeight>></$link> |<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/metrics/lineheight\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/metrics/bodyfontsize\"><<lingo Metrics/BodyFontSize>></$link> |<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/metrics/bodyfontsize\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/metrics/bodylineheight\"><<lingo Metrics/BodyLineHeight>></$link> |<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/metrics/bodylineheight\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/metrics/storyleft\"><<lingo Metrics/StoryLeft>></$link><br>//<<lingo Metrics/StoryLeft/Hint>>// |^<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/metrics/storyleft\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/metrics/storytop\"><<lingo Metrics/StoryTop>></$link><br>//<<lingo Metrics/StoryTop/Hint>>// |^<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/metrics/storytop\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/metrics/storyright\"><<lingo Metrics/StoryRight>></$link><br>//<<lingo Metrics/StoryRight/Hint>>// |^<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/metrics/storyright\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/metrics/storywidth\"><<lingo Metrics/StoryWidth>></$link><br>//<<lingo Metrics/StoryWidth/Hint>>// |^<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/metrics/storywidth\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/metrics/tiddlerwidth\"><<lingo Metrics/TiddlerWidth>></$link><br>//<<lingo Metrics/TiddlerWidth/Hint>>//<br> |^<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/metrics/tiddlerwidth\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint\"><<lingo Metrics/SidebarBreakpoint>></$link><br>//<<lingo Metrics/SidebarBreakpoint/Hint>>// |^<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/metrics/sidebarwidth\"><<lingo Metrics/SidebarWidth>></$link><br>//<<lingo Metrics/SidebarWidth/Hint>>// |^<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/metrics/sidebarwidth\" default=\"\" tag=\"input\"/> |\n"
},
"$:/themes/tiddlywiki/vanilla/base": {
"title": "$:/themes/tiddlywiki/vanilla/base",
"tags": "[[$:/tags/Stylesheet]]",
"text": "\\define custom-background-datauri()\n<$set name=\"background\" value={{$:/themes/tiddlywiki/vanilla/settings/backgroundimage}}>\n<$list filter=\"[<background>is[image]]\">\n`background: url(`\n<$list filter=\"[<background>!has[_canonical_uri]]\">\n`\"`<$macrocall $name=\"datauri\" title={{$:/themes/tiddlywiki/vanilla/settings/backgroundimage}}/>`\"`\n</$list>\n<$list filter=\"[<background>has[_canonical_uri]]\">\n`\"`<$view tiddler={{$:/themes/tiddlywiki/vanilla/settings/backgroundimage}} field=\"_canonical_uri\"/>`\"`\n</$list>\n`) center center;`\n`background-attachment: `{{$:/themes/tiddlywiki/vanilla/settings/backgroundimageattachment}}`;\n-webkit-background-size:` {{$:/themes/tiddlywiki/vanilla/settings/backgroundimagesize}}`;\n-moz-background-size:` {{$:/themes/tiddlywiki/vanilla/settings/backgroundimagesize}}`;\n-o-background-size:` {{$:/themes/tiddlywiki/vanilla/settings/backgroundimagesize}}`;\nbackground-size:` {{$:/themes/tiddlywiki/vanilla/settings/backgroundimagesize}}`;`\n</$list>\n</$set>\n\\end\n\n\\define if-fluid-fixed(text,hiddenSidebarText)\n<$reveal state=\"$:/themes/tiddlywiki/vanilla/options/sidebarlayout\" type=\"match\" text=\"fluid-fixed\">\n$text$\n<$reveal state=\"$:/state/sidebar\" type=\"nomatch\" text=\"yes\" default=\"yes\">\n$hiddenSidebarText$\n</$reveal>\n</$reveal>\n\\end\n\n\\define if-editor-height-fixed(then,else)\n<$reveal state=\"$:/config/TextEditor/EditorHeight/Mode\" type=\"match\" text=\"fixed\">\n$then$\n</$reveal>\n<$reveal state=\"$:/config/TextEditor/EditorHeight/Mode\" type=\"match\" text=\"auto\">\n$else$\n</$reveal>\n\\end\n\n\\rules only filteredtranscludeinline transcludeinline macrodef macrocallinline macrocallblock\n\n/*\n** Start with the normalize CSS reset, and then belay some of its effects\n*/\n\n{{$:/themes/tiddlywiki/vanilla/reset}}\n\n*, input[type=\"search\"] {\n\tbox-sizing: border-box;\n\t-moz-box-sizing: border-box;\n\t-webkit-box-sizing: border-box;\n}\n\nhtml button {\n\tline-height: 1.2;\n\tcolor: <<colour button-foreground>>;\n\tbackground: <<colour button-background>>;\n\tborder-color: <<colour button-border>>;\n}\n\n/*\n** Basic element styles\n*/\n\nhtml {\n\tfont-family: {{$:/themes/tiddlywiki/vanilla/settings/fontfamily}};\n\ttext-rendering: optimizeLegibility; /* Enables kerning and ligatures etc. */\n\t-webkit-font-smoothing: antialiased;\n\t-moz-osx-font-smoothing: grayscale;\n}\n\nhtml:-webkit-full-screen {\n\tbackground-color: <<colour page-background>>;\n}\n\nbody.tc-body {\n\tfont-size: {{$:/themes/tiddlywiki/vanilla/metrics/fontsize}};\n\tline-height: {{$:/themes/tiddlywiki/vanilla/metrics/lineheight}};\n\tword-wrap: break-word;\n\t<<custom-background-datauri>>\n\tcolor: <<colour foreground>>;\n\tbackground-color: <<colour page-background>>;\n\tfill: <<colour foreground>>;\n}\n\n<<if-background-attachment \"\"\"\n\nbody.tc-body {\n background-color: transparent;\n}\n\n\"\"\">>\n\nh1, h2, h3, h4, h5, h6 {\n\tline-height: 1.2;\n\tfont-weight: 300;\n}\n\npre {\n\tdisplay: block;\n\tpadding: 14px;\n\tmargin-top: 1em;\n\tmargin-bottom: 1em;\n\tword-break: normal;\n\tword-wrap: break-word;\n\twhite-space: {{$:/themes/tiddlywiki/vanilla/options/codewrapping}};\n\tbackground-color: <<colour pre-background>>;\n\tborder: 1px solid <<colour pre-border>>;\n\tpadding: 0 3px 2px;\n\tborder-radius: 3px;\n\tfont-family: {{$:/themes/tiddlywiki/vanilla/settings/codefontfamily}};\n}\n\ncode {\n\tcolor: <<colour code-foreground>>;\n\tbackground-color: <<colour code-background>>;\n\tborder: 1px solid <<colour code-border>>;\n\twhite-space: {{$:/themes/tiddlywiki/vanilla/options/codewrapping}};\n\tpadding: 0 3px 2px;\n\tborder-radius: 3px;\n\tfont-family: {{$:/themes/tiddlywiki/vanilla/settings/codefontfamily}};\n}\n\nblockquote {\n\tborder-left: 5px solid <<colour blockquote-bar>>;\n\tmargin-left: 25px;\n\tpadding-left: 10px;\n\tquotes: \"\\201C\"\"\\201D\"\"\\2018\"\"\\2019\";\n}\n\nblockquote.tc-big-quote {\n\tfont-family: Georgia, serif;\n\tposition: relative;\n\tbackground: <<colour pre-background>>;\n\tborder-left: none;\n\tmargin-left: 50px;\n\tmargin-right: 50px;\n\tpadding: 10px;\n border-radius: 8px;\n}\n\nblockquote.tc-big-quote cite:before {\n\tcontent: \"\\2014 \\2009\";\n}\n\nblockquote.tc-big-quote:before {\n\tfont-family: Georgia, serif;\n\tcolor: <<colour blockquote-bar>>;\n\tcontent: open-quote;\n\tfont-size: 8em;\n\tline-height: 0.1em;\n\tmargin-right: 0.25em;\n\tvertical-align: -0.4em;\n\tposition: absolute;\n left: -50px;\n top: 42px;\n}\n\nblockquote.tc-big-quote:after {\n\tfont-family: Georgia, serif;\n\tcolor: <<colour blockquote-bar>>;\n\tcontent: close-quote;\n\tfont-size: 8em;\n\tline-height: 0.1em;\n\tmargin-right: 0.25em;\n\tvertical-align: -0.4em;\n\tposition: absolute;\n right: -80px;\n bottom: -20px;\n}\n\ndl dt {\n\tfont-weight: bold;\n\tmargin-top: 6px;\n}\n\ntextarea,\ninput[type=text],\ninput[type=search],\ninput[type=\"\"],\ninput:not([type]) {\n\tcolor: <<colour foreground>>;\n\tbackground: <<colour background>>;\n}\n\ninput[type=\"checkbox\"] {\n vertical-align: middle;\n}\n\n.tc-muted {\n\tcolor: <<colour muted-foreground>>;\n}\n\nsvg.tc-image-button {\n\tpadding: 0px 1px 1px 0px;\n}\n\n.tc-icon-wrapper > svg {\n\twidth: 1em;\n\theight: 1em;\n}\n\nkbd {\n\tdisplay: inline-block;\n\tpadding: 3px 5px;\n\tfont-size: 0.8em;\n\tline-height: 1.2;\n\tcolor: <<colour foreground>>;\n\tvertical-align: middle;\n\tbackground-color: <<colour background>>;\n\tborder: solid 1px <<colour muted-foreground>>;\n\tborder-bottom-color: <<colour muted-foreground>>;\n\tborder-radius: 3px;\n\tbox-shadow: inset 0 -1px 0 <<colour muted-foreground>>;\n}\n\n/*\nMarkdown likes putting code elements inside pre elements\n*/\npre > code {\n\tpadding: 0;\n\tborder: none;\n\tbackground-color: inherit;\n\tcolor: inherit;\n}\n\ntable {\n\tborder: 1px solid <<colour table-border>>;\n\twidth: auto;\n\tmax-width: 100%;\n\tcaption-side: bottom;\n\tmargin-top: 1em;\n\tmargin-bottom: 1em;\n}\n\ntable th, table td {\n\tpadding: 0 7px 0 7px;\n\tborder-top: 1px solid <<colour table-border>>;\n\tborder-left: 1px solid <<colour table-border>>;\n}\n\ntable thead tr td, table th {\n\tbackground-color: <<colour table-header-background>>;\n\tfont-weight: bold;\n}\n\ntable tfoot tr td {\n\tbackground-color: <<colour table-footer-background>>;\n}\n\n.tc-csv-table {\n\twhite-space: nowrap;\n}\n\n.tc-tiddler-frame img,\n.tc-tiddler-frame svg,\n.tc-tiddler-frame canvas,\n.tc-tiddler-frame embed,\n.tc-tiddler-frame iframe {\n\tmax-width: 100%;\n}\n\n.tc-tiddler-body > embed,\n.tc-tiddler-body > iframe {\n\twidth: 100%;\n\theight: 600px;\n}\n\n/*\n** Links\n*/\n\nbutton.tc-tiddlylink,\na.tc-tiddlylink {\n\ttext-decoration: none;\n\tfont-weight: 500;\n\tcolor: <<colour tiddler-link-foreground>>;\n\t-webkit-user-select: inherit; /* Otherwise the draggable attribute makes links impossible to select */\n}\n\n.tc-sidebar-lists a.tc-tiddlylink {\n\tcolor: <<colour sidebar-tiddler-link-foreground>>;\n}\n\n.tc-sidebar-lists a.tc-tiddlylink:hover {\n\tcolor: <<colour sidebar-tiddler-link-foreground-hover>>;\n}\n\nbutton.tc-tiddlylink:hover,\na.tc-tiddlylink:hover {\n\ttext-decoration: underline;\n}\n\na.tc-tiddlylink-resolves {\n}\n\na.tc-tiddlylink-shadow {\n\tfont-weight: bold;\n}\n\na.tc-tiddlylink-shadow.tc-tiddlylink-resolves {\n\tfont-weight: normal;\n}\n\na.tc-tiddlylink-missing {\n\tfont-style: italic;\n}\n\na.tc-tiddlylink-external {\n\ttext-decoration: underline;\n\tcolor: <<colour external-link-foreground>>;\n\tbackground-color: <<colour external-link-background>>;\n}\n\na.tc-tiddlylink-external:visited {\n\tcolor: <<colour external-link-foreground-visited>>;\n\tbackground-color: <<colour external-link-background-visited>>;\n}\n\na.tc-tiddlylink-external:hover {\n\tcolor: <<colour external-link-foreground-hover>>;\n\tbackground-color: <<colour external-link-background-hover>>;\n}\n\n/*\n** Drag and drop styles\n*/\n\n.tc-tiddler-dragger {\n\tposition: relative;\n\tz-index: -10000;\n}\n\n.tc-tiddler-dragger-inner {\n\tposition: absolute;\n\ttop: -1000px;\n\tleft: -1000px;\n\tdisplay: inline-block;\n\tpadding: 8px 20px;\n\tfont-size: 16.9px;\n\tfont-weight: bold;\n\tline-height: 20px;\n\tcolor: <<colour dragger-foreground>>;\n\ttext-shadow: 0 1px 0 rgba(0, 0, 0, 1);\n\twhite-space: nowrap;\n\tvertical-align: baseline;\n\tbackground-color: <<colour dragger-background>>;\n\tborder-radius: 20px;\n}\n\n.tc-tiddler-dragger-cover {\n\tposition: absolute;\n\tbackground-color: <<colour page-background>>;\n}\n\n.tc-dropzone {\n\tposition: relative;\n}\n\n.tc-dropzone.tc-dragover:before {\n\tz-index: 10000;\n\tdisplay: block;\n\tposition: fixed;\n\ttop: 0;\n\tleft: 0;\n\tright: 0;\n\tbackground: <<colour dropzone-background>>;\n\ttext-align: center;\n\tcontent: \"<<lingo DropMessage>>\";\n}\n\n.tc-droppable > .tc-droppable-placeholder {\n\tdisplay: none;\n}\n\n.tc-droppable.tc-dragover > .tc-droppable-placeholder {\n\tdisplay: block;\n\tborder: 2px dashed <<colour dropzone-background>>;\n}\n\n.tc-draggable {\n\tcursor: move;\n}\n\n/*\n** Plugin reload warning\n*/\n\n.tc-plugin-reload-warning {\n\tz-index: 1000;\n\tdisplay: block;\n\tposition: fixed;\n\ttop: 0;\n\tleft: 0;\n\tright: 0;\n\tbackground: <<colour alert-background>>;\n\ttext-align: center;\n}\n\n/*\n** Buttons\n*/\n\nbutton svg, button img, label svg, label img {\n\tvertical-align: middle;\n}\n\n.tc-btn-invisible {\n\tpadding: 0;\n\tmargin: 0;\n\tbackground: none;\n\tborder: none;\n cursor: pointer;\n}\n\n.tc-btn-boxed {\n\tfont-size: 0.6em;\n\tpadding: 0.2em;\n\tmargin: 1px;\n\tbackground: none;\n\tborder: 1px solid <<colour tiddler-controls-foreground>>;\n\tborder-radius: 0.25em;\n}\n\nhtml body.tc-body .tc-btn-boxed svg {\n\tfont-size: 1.6666em;\n}\n\n.tc-btn-boxed:hover {\n\tbackground: <<colour muted-foreground>>;\n\tcolor: <<colour background>>;\n}\n\nhtml body.tc-body .tc-btn-boxed:hover svg {\n\tfill: <<colour background>>;\n}\n\n.tc-btn-rounded {\n\tfont-size: 0.5em;\n\tline-height: 2;\n\tpadding: 0em 0.3em 0.2em 0.4em;\n\tmargin: 1px;\n\tborder: 1px solid <<colour muted-foreground>>;\n\tbackground: <<colour muted-foreground>>;\n\tcolor: <<colour background>>;\n\tborder-radius: 2em;\n}\n\nhtml body.tc-body .tc-btn-rounded svg {\n\tfont-size: 1.6666em;\n\tfill: <<colour background>>;\n}\n\n.tc-btn-rounded:hover {\n\tborder: 1px solid <<colour muted-foreground>>;\n\tbackground: <<colour background>>;\n\tcolor: <<colour muted-foreground>>;\n}\n\nhtml body.tc-body .tc-btn-rounded:hover svg {\n\tfill: <<colour muted-foreground>>;\n}\n\n.tc-btn-icon svg {\n\theight: 1em;\n\twidth: 1em;\n\tfill: <<colour muted-foreground>>;\n}\n\n.tc-btn-text {\n\tpadding: 0;\n\tmargin: 0;\n}\n\n/* used for documentation \"fake\" buttons */\n.tc-btn-standard {\n\tline-height: 1.8;\n\tcolor: #667;\n\tbackground-color: #e0e0e0;\n\tborder: 1px solid #888;\n\tpadding: 2px 1px 2px 1px;\n\tmargin: 1px 4px 1px 4px;\n}\n\n.tc-btn-big-green {\n\tdisplay: inline-block;\n\tpadding: 8px;\n\tmargin: 4px 8px 4px 8px;\n\tbackground: <<colour download-background>>;\n\tcolor: <<colour download-foreground>>;\n\tfill: <<colour download-foreground>>;\n\tborder: none;\n\tfont-size: 1.2em;\n\tline-height: 1.4em;\n\ttext-decoration: none;\n}\n\n.tc-btn-big-green svg,\n.tc-btn-big-green img {\n\theight: 2em;\n\twidth: 2em;\n\tvertical-align: middle;\n\tfill: <<colour download-foreground>>;\n}\n\n.tc-sidebar-lists input {\n\tcolor: <<colour foreground>>;\n}\n\n.tc-sidebar-lists button {\n\tcolor: <<colour sidebar-button-foreground>>;\n\tfill: <<colour sidebar-button-foreground>>;\n}\n\n.tc-sidebar-lists button.tc-btn-mini {\n\tcolor: <<colour sidebar-muted-foreground>>;\n}\n\n.tc-sidebar-lists button.tc-btn-mini:hover {\n\tcolor: <<colour sidebar-muted-foreground-hover>>;\n}\n\nbutton svg.tc-image-button, button .tc-image-button img {\n\theight: 1em;\n\twidth: 1em;\n}\n\n.tc-unfold-banner {\n\tposition: absolute;\n\tpadding: 0;\n\tmargin: 0;\n\tbackground: none;\n\tborder: none;\n\twidth: 100%;\n\twidth: calc(100% + 2px);\n\tmargin-left: -43px;\n\ttext-align: center;\n\tborder-top: 2px solid <<colour tiddler-info-background>>;\n\tmargin-top: 4px;\n}\n\n.tc-unfold-banner:hover {\n\tbackground: <<colour tiddler-info-background>>;\n\tborder-top: 2px solid <<colour tiddler-info-border>>;\n}\n\n.tc-unfold-banner svg, .tc-fold-banner svg {\n\theight: 0.75em;\n\tfill: <<colour tiddler-controls-foreground>>;\n}\n\n.tc-unfold-banner:hover svg, .tc-fold-banner:hover svg {\n\tfill: <<colour tiddler-controls-foreground-hover>>;\n}\n\n.tc-fold-banner {\n\tposition: absolute;\n\tpadding: 0;\n\tmargin: 0;\n\tbackground: none;\n\tborder: none;\n\twidth: 23px;\n\ttext-align: center;\n\tmargin-left: -35px;\n\ttop: 6px;\n\tbottom: 6px;\n}\n\n.tc-fold-banner:hover {\n\tbackground: <<colour tiddler-info-background>>;\n}\n\n@media (max-width: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}}) {\n\n\t.tc-unfold-banner {\n\t\tposition: static;\n\t\twidth: calc(100% + 59px);\n\t}\n\n\t.tc-fold-banner {\n\t\twidth: 16px;\n\t\tmargin-left: -16px;\n\t\tfont-size: 0.75em;\n\t}\n\n}\n\n/*\n** Tags and missing tiddlers\n*/\n\n.tc-tag-list-item {\n\tposition: relative;\n\tdisplay: inline-block;\n\tmargin-right: 7px;\n}\n\n.tc-tags-wrapper {\n\tmargin: 4px 0 14px 0;\n}\n\n.tc-missing-tiddler-label {\n\tfont-style: italic;\n\tfont-weight: normal;\n\tdisplay: inline-block;\n\tfont-size: 11.844px;\n\tline-height: 14px;\n\twhite-space: nowrap;\n\tvertical-align: baseline;\n}\n\nbutton.tc-tag-label, span.tc-tag-label {\n\tdisplay: inline-block;\n\tpadding: 0.16em 0.7em;\n\tfont-size: 0.9em;\n\tfont-weight: 400;\n\tline-height: 1.2em;\n\tcolor: <<colour tag-foreground>>;\n\twhite-space: nowrap;\n\tvertical-align: baseline;\n\tbackground-color: <<colour tag-background>>;\n\tborder-radius: 1em;\n}\n\n.tc-untagged-separator {\n\twidth: 10em;\n\tleft: 0;\n\tmargin-left: 0;\n\tborder: 0;\n\theight: 1px;\n\tbackground: <<colour tab-divider>>;\n}\n\nbutton.tc-untagged-label {\n\tbackground-color: <<colour untagged-background>>;\n}\n\n.tc-tag-label svg, .tc-tag-label img {\n\theight: 1em;\n\twidth: 1em;\n\tvertical-align: text-bottom;\n}\n\n.tc-tag-manager-table .tc-tag-label {\n\twhite-space: normal;\n}\n\n.tc-tag-manager-tag {\n\twidth: 100%;\n}\n\nbutton.tc-btn-invisible.tc-remove-tag-button {\n\toutline: none;\n}\n\n/*\n** Page layout\n*/\n\n.tc-topbar {\n\tposition: fixed;\n\tz-index: 1200;\n}\n\n.tc-topbar-left {\n\tleft: 29px;\n\ttop: 5px;\n}\n\n.tc-topbar-right {\n\ttop: 5px;\n\tright: 29px;\n}\n\n.tc-topbar button {\n\tpadding: 8px;\n}\n\n.tc-topbar svg {\n\tfill: <<colour muted-foreground>>;\n}\n\n.tc-topbar button:hover svg {\n\tfill: <<colour foreground>>;\n}\n\n.tc-sidebar-header {\n\tcolor: <<colour sidebar-foreground>>;\n\tfill: <<colour sidebar-foreground>>;\n}\n\n.tc-sidebar-header .tc-title a.tc-tiddlylink-resolves {\n\tfont-weight: 300;\n}\n\n.tc-sidebar-header .tc-sidebar-lists p {\n\tmargin-top: 3px;\n\tmargin-bottom: 3px;\n}\n\n.tc-sidebar-header .tc-missing-tiddler-label {\n\tcolor: <<colour sidebar-foreground>>;\n}\n\n.tc-advanced-search input {\n\twidth: 60%;\n}\n\n.tc-search a svg {\n\twidth: 1.2em;\n\theight: 1.2em;\n\tvertical-align: middle;\n}\n\n.tc-page-controls {\n\tmargin-top: 14px;\n\tfont-size: 1.5em;\n}\n\n.tc-page-controls .tc-drop-down {\n font-size: 1rem;\n}\n\n.tc-page-controls button {\n\tmargin-right: 0.5em;\n}\n\n.tc-page-controls a.tc-tiddlylink:hover {\n\ttext-decoration: none;\n}\n\n.tc-page-controls img {\n\twidth: 1em;\n}\n\n.tc-page-controls svg {\n\tfill: <<colour sidebar-controls-foreground>>;\n}\n\n.tc-page-controls button:hover svg, .tc-page-controls a:hover svg {\n\tfill: <<colour sidebar-controls-foreground-hover>>;\n}\n\n.tc-menu-list-item {\n\twhite-space: nowrap;\n}\n\n.tc-menu-list-count {\n\tfont-weight: bold;\n}\n\n.tc-menu-list-subitem {\n\tpadding-left: 7px;\n}\n\n.tc-story-river {\n\tposition: relative;\n}\n\n@media (max-width: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}}) {\n\n\t.tc-sidebar-header {\n\t\tpadding: 14px;\n\t\tmin-height: 32px;\n\t\tmargin-top: {{$:/themes/tiddlywiki/vanilla/metrics/storytop}};\n\t}\n\n\t.tc-story-river {\n\t\tposition: relative;\n\t\tpadding: 0;\n\t}\n}\n\n@media (min-width: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}}) {\n\n\t.tc-message-box {\n\t\tmargin: 21px -21px 21px -21px;\n\t}\n\n\t.tc-sidebar-scrollable {\n\t\tposition: fixed;\n\t\ttop: {{$:/themes/tiddlywiki/vanilla/metrics/storytop}};\n\t\tleft: {{$:/themes/tiddlywiki/vanilla/metrics/storyright}};\n\t\tbottom: 0;\n\t\tright: 0;\n\t\toverflow-y: auto;\n\t\toverflow-x: auto;\n\t\t-webkit-overflow-scrolling: touch;\n\t\tmargin: 0 0 0 -42px;\n\t\tpadding: 71px 0 28px 42px;\n\t}\n\n\thtml[dir=\"rtl\"] .tc-sidebar-scrollable {\n\t\tleft: auto;\n\t\tright: {{$:/themes/tiddlywiki/vanilla/metrics/storyright}};\n\t}\n\n\t.tc-story-river {\n\t\tposition: relative;\n\t\tleft: {{$:/themes/tiddlywiki/vanilla/metrics/storyleft}};\n\t\ttop: {{$:/themes/tiddlywiki/vanilla/metrics/storytop}};\n\t\twidth: {{$:/themes/tiddlywiki/vanilla/metrics/storywidth}};\n\t\tpadding: 42px 42px 42px 42px;\n\t}\n\n<<if-no-sidebar \"\n\n\t.tc-story-river {\n\t\twidth: calc(100% - {{$:/themes/tiddlywiki/vanilla/metrics/storyleft}});\n\t}\n\n\">>\n\n}\n\n@media print {\n\n\tbody.tc-body {\n\t\tbackground-color: transparent;\n\t}\n\n\t.tc-sidebar-header, .tc-topbar {\n\t\tdisplay: none;\n\t}\n\n\t.tc-story-river {\n\t\tmargin: 0;\n\t\tpadding: 0;\n\t}\n\n\t.tc-story-river .tc-tiddler-frame {\n\t\tmargin: 0;\n\t\tborder: none;\n\t\tpadding: 0;\n\t}\n}\n\n/*\n** Tiddler styles\n*/\n\n.tc-tiddler-frame {\n\tposition: relative;\n\tmargin-bottom: 28px;\n\tbackground-color: <<colour tiddler-background>>;\n\tborder: 1px solid <<colour tiddler-border>>;\n}\n\n{{$:/themes/tiddlywiki/vanilla/sticky}}\n\n.tc-tiddler-info {\n\tpadding: 14px 42px 14px 42px;\n\tbackground-color: <<colour tiddler-info-background>>;\n\tborder-top: 1px solid <<colour tiddler-info-border>>;\n\tborder-bottom: 1px solid <<colour tiddler-info-border>>;\n}\n\n.tc-tiddler-info p {\n\tmargin-top: 3px;\n\tmargin-bottom: 3px;\n}\n\n.tc-tiddler-info .tc-tab-buttons button.tc-tab-selected {\n\tbackground-color: <<colour tiddler-info-tab-background>>;\n\tborder-bottom: 1px solid <<colour tiddler-info-tab-background>>;\n}\n\n.tc-view-field-table {\n\twidth: 100%;\n}\n\n.tc-view-field-name {\n\twidth: 1%; /* Makes this column be as narrow as possible */\n\ttext-align: right;\n\tfont-style: italic;\n\tfont-weight: 200;\n}\n\n.tc-view-field-value {\n}\n\n@media (max-width: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}}) {\n\t.tc-tiddler-frame {\n\t\tpadding: 14px 14px 14px 14px;\n\t}\n\n\t.tc-tiddler-info {\n\t\tmargin: 0 -14px 0 -14px;\n\t}\n}\n\n@media (min-width: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}}) {\n\t.tc-tiddler-frame {\n\t\tpadding: 28px 42px 42px 42px;\n\t\twidth: {{$:/themes/tiddlywiki/vanilla/metrics/tiddlerwidth}};\n\t\tborder-radius: 2px;\n\t}\n\n<<if-no-sidebar \"\n\n\t.tc-tiddler-frame {\n\t\twidth: 100%;\n\t}\n\n\">>\n\n\t.tc-tiddler-info {\n\t\tmargin: 0 -42px 0 -42px;\n\t}\n}\n\n.tc-site-title,\n.tc-titlebar {\n\tfont-weight: 300;\n\tfont-size: 2.35em;\n\tline-height: 1.2em;\n\tcolor: <<colour tiddler-title-foreground>>;\n\tmargin: 0;\n}\n\n.tc-site-title {\n\tcolor: <<colour site-title-foreground>>;\n}\n\n.tc-tiddler-title-icon {\n\tvertical-align: middle;\n}\n\n.tc-system-title-prefix {\n\tcolor: <<colour muted-foreground>>;\n}\n\n.tc-titlebar h2 {\n\tfont-size: 1em;\n\tdisplay: inline;\n}\n\n.tc-titlebar img {\n\theight: 1em;\n}\n\n.tc-subtitle {\n\tfont-size: 0.9em;\n\tcolor: <<colour tiddler-subtitle-foreground>>;\n\tfont-weight: 300;\n}\n\n.tc-tiddler-missing .tc-title {\n font-style: italic;\n font-weight: normal;\n}\n\n.tc-tiddler-frame .tc-tiddler-controls {\n\tfloat: right;\n}\n\n.tc-tiddler-controls .tc-drop-down {\n\tfont-size: 0.6em;\n}\n\n.tc-tiddler-controls .tc-drop-down .tc-drop-down {\n\tfont-size: 1em;\n}\n\n.tc-tiddler-controls > span > button,\n.tc-tiddler-controls > span > span > button,\n.tc-tiddler-controls > span > span > span > button {\n\tvertical-align: baseline;\n\tmargin-left:5px;\n}\n\n.tc-tiddler-controls button svg, .tc-tiddler-controls button img,\n.tc-search button svg, .tc-search a svg {\n\tfill: <<colour tiddler-controls-foreground>>;\n}\n\n.tc-tiddler-controls button svg, .tc-tiddler-controls button img {\n\theight: 0.75em;\n}\n\n.tc-search button svg, .tc-search a svg {\n height: 1.2em;\n width: 1.2em;\n margin: 0 0.25em;\n}\n\n.tc-tiddler-controls button.tc-selected svg,\n.tc-page-controls button.tc-selected svg {\n\tfill: <<colour tiddler-controls-foreground-selected>>;\n}\n\n.tc-tiddler-controls button.tc-btn-invisible:hover svg,\n.tc-search button:hover svg, .tc-search a:hover svg {\n\tfill: <<colour tiddler-controls-foreground-hover>>;\n}\n\n@media print {\n\t.tc-tiddler-controls {\n\t\tdisplay: none;\n\t}\n}\n\n.tc-tiddler-help { /* Help prompts within tiddler template */\n\tcolor: <<colour muted-foreground>>;\n\tmargin-top: 14px;\n}\n\n.tc-tiddler-help a.tc-tiddlylink {\n\tcolor: <<colour very-muted-foreground>>;\n}\n\n.tc-tiddler-frame .tc-edit-texteditor {\n\twidth: 100%;\n\tmargin: 4px 0 4px 0;\n}\n\n.tc-tiddler-frame input.tc-edit-texteditor,\n.tc-tiddler-frame textarea.tc-edit-texteditor,\n.tc-tiddler-frame iframe.tc-edit-texteditor {\n\tpadding: 3px 3px 3px 3px;\n\tborder: 1px solid <<colour tiddler-editor-border>>;\n\tbackground-color: <<colour tiddler-editor-background>>;\n\tline-height: 1.3em;\n\t-webkit-appearance: none;\n\tfont-family: {{$:/themes/tiddlywiki/vanilla/settings/editorfontfamily}};\n}\n\n.tc-tiddler-frame .tc-binary-warning {\n\twidth: 100%;\n\theight: 5em;\n\ttext-align: center;\n\tpadding: 3em 3em 6em 3em;\n\tbackground: <<colour alert-background>>;\n\tborder: 1px solid <<colour alert-border>>;\n}\n\ncanvas.tc-edit-bitmapeditor {\n\tborder: 6px solid <<colour tiddler-editor-border-image>>;\n\tcursor: crosshair;\n\t-moz-user-select: none;\n\t-webkit-user-select: none;\n\t-ms-user-select: none;\n\tmargin-top: 6px;\n\tmargin-bottom: 6px;\n}\n\n.tc-edit-bitmapeditor-width {\n\tdisplay: block;\n}\n\n.tc-edit-bitmapeditor-height {\n\tdisplay: block;\n}\n\n.tc-tiddler-body {\n\tclear: both;\n}\n\n.tc-tiddler-frame .tc-tiddler-body {\n\tfont-size: {{$:/themes/tiddlywiki/vanilla/metrics/bodyfontsize}};\n\tline-height: {{$:/themes/tiddlywiki/vanilla/metrics/bodylineheight}};\n}\n\n.tc-titlebar, .tc-tiddler-edit-title {\n\toverflow: hidden; /* https://github.com/Jermolene/TiddlyWiki5/issues/282 */\n}\n\nhtml body.tc-body.tc-single-tiddler-window {\n\tmargin: 1em;\n\tbackground: <<colour tiddler-background>>;\n}\n\n.tc-single-tiddler-window img,\n.tc-single-tiddler-window svg,\n.tc-single-tiddler-window canvas,\n.tc-single-tiddler-window embed,\n.tc-single-tiddler-window iframe {\n\tmax-width: 100%;\n}\n\n/*\n** Editor\n*/\n\n.tc-editor-toolbar {\n\tmargin-top: 8px;\n}\n\n.tc-editor-toolbar button {\n\tvertical-align: middle;\n\tbackground-color: <<colour tiddler-controls-foreground>>;\n\tfill: <<colour tiddler-controls-foreground-selected>>;\n\tborder-radius: 4px;\n\tpadding: 3px;\n\tmargin: 2px 0 2px 4px;\n}\n\n.tc-editor-toolbar button.tc-text-editor-toolbar-item-adjunct {\n\tmargin-left: 1px;\n\twidth: 1em;\n\tborder-radius: 8px;\n}\n\n.tc-editor-toolbar button.tc-text-editor-toolbar-item-start-group {\n\tmargin-left: 11px;\n}\n\n.tc-editor-toolbar button.tc-selected {\n\tbackground-color: <<colour primary>>;\n}\n\n.tc-editor-toolbar button svg {\n\twidth: 1.6em;\n\theight: 1.2em;\n}\n\n.tc-editor-toolbar button:hover {\n\tbackground-color: <<colour tiddler-controls-foreground-selected>>;\n\tfill: <<colour background>>;\n\tcolor: <<colour background>>;\n}\n\n.tc-editor-toolbar .tc-text-editor-toolbar-more {\n\twhite-space: normal;\n}\n\n.tc-editor-toolbar .tc-text-editor-toolbar-more button {\n\tdisplay: inline-block;\n\tpadding: 3px;\n\twidth: auto;\n}\n\n.tc-editor-toolbar .tc-search-results {\n\tpadding: 0;\n}\n\n/*\n** Adjustments for fluid-fixed mode\n*/\n\n@media (min-width: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}}) {\n\n<<if-fluid-fixed text:\"\"\"\n\n\t.tc-story-river {\n\t\tpadding-right: 0;\n\t\tposition: relative;\n\t\twidth: auto;\n\t\tleft: 0;\n\t\tmargin-left: {{$:/themes/tiddlywiki/vanilla/metrics/storyleft}};\n\t\tmargin-right: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarwidth}};\n\t}\n\n\t.tc-tiddler-frame {\n\t\twidth: 100%;\n\t}\n\n\t.tc-sidebar-scrollable {\n\t\tleft: auto;\n\t\tbottom: 0;\n\t\tright: 0;\n\t\twidth: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarwidth}};\n\t}\n\n\tbody.tc-body .tc-storyview-zoomin-tiddler {\n\t\twidth: 100%;\n\t\twidth: calc(100% - 42px);\n\t}\n\n\"\"\" hiddenSidebarText:\"\"\"\n\n\t.tc-story-river {\n\t\tpadding-right: 3em;\n\t\tmargin-right: 0;\n\t}\n\n\tbody.tc-body .tc-storyview-zoomin-tiddler {\n\t\twidth: 100%;\n\t\twidth: calc(100% - 84px);\n\t}\n\n\"\"\">>\n\n}\n\n/*\n** Toolbar buttons\n*/\n\n.tc-page-controls svg.tc-image-new-button {\n fill: <<colour toolbar-new-button>>;\n}\n\n.tc-page-controls svg.tc-image-options-button {\n fill: <<colour toolbar-options-button>>;\n}\n\n.tc-page-controls svg.tc-image-save-button {\n fill: <<colour toolbar-save-button>>;\n}\n\n.tc-tiddler-controls button svg.tc-image-info-button {\n fill: <<colour toolbar-info-button>>;\n}\n\n.tc-tiddler-controls button svg.tc-image-edit-button {\n fill: <<colour toolbar-edit-button>>;\n}\n\n.tc-tiddler-controls button svg.tc-image-close-button {\n fill: <<colour toolbar-close-button>>;\n}\n\n.tc-tiddler-controls button svg.tc-image-delete-button {\n fill: <<colour toolbar-delete-button>>;\n}\n\n.tc-tiddler-controls button svg.tc-image-cancel-button {\n fill: <<colour toolbar-cancel-button>>;\n}\n\n.tc-tiddler-controls button svg.tc-image-done-button {\n fill: <<colour toolbar-done-button>>;\n}\n\n/*\n** Tiddler edit mode\n*/\n\n.tc-tiddler-edit-frame em.tc-edit {\n\tcolor: <<colour muted-foreground>>;\n\tfont-style: normal;\n}\n\n.tc-edit-type-dropdown a.tc-tiddlylink-missing {\n\tfont-style: normal;\n}\n\n.tc-edit-tags {\n\tborder: 1px solid <<colour tiddler-editor-border>>;\n\tpadding: 4px 8px 4px 8px;\n}\n\n.tc-edit-add-tag {\n\tdisplay: inline-block;\n}\n\n.tc-edit-add-tag .tc-add-tag-name input {\n\twidth: 50%;\n}\n\n.tc-edit-add-tag .tc-keyboard {\n\tdisplay:inline;\n}\n\n.tc-edit-tags .tc-tag-label {\n\tdisplay: inline-block;\n}\n\n.tc-edit-tags-list {\n\tmargin: 14px 0 14px 0;\n}\n\n.tc-remove-tag-button {\n\tpadding-left: 4px;\n}\n\n.tc-tiddler-preview {\n\toverflow: auto;\n}\n\n.tc-tiddler-preview-preview {\n\tfloat: right;\n\twidth: 49%;\n\tborder: 1px solid <<colour tiddler-editor-border>>;\n\tmargin: 4px 0 3px 3px;\n\tpadding: 3px 3px 3px 3px;\n}\n\n<<if-editor-height-fixed then:\"\"\"\n\n.tc-tiddler-preview-preview {\n\toverflow-y: scroll;\n\theight: {{$:/config/TextEditor/EditorHeight/Height}};\n}\n\n\"\"\">>\n\n.tc-tiddler-frame .tc-tiddler-preview .tc-edit-texteditor {\n\twidth: 49%;\n}\n\n.tc-tiddler-frame .tc-tiddler-preview canvas.tc-edit-bitmapeditor {\n\tmax-width: 49%;\n}\n\n.tc-edit-fields {\n\twidth: 100%;\n}\n\n\n.tc-edit-fields table, .tc-edit-fields tr, .tc-edit-fields td {\n\tborder: none;\n\tpadding: 4px;\n}\n\n.tc-edit-fields > tbody > .tc-edit-field:nth-child(odd) {\n\tbackground-color: <<colour tiddler-editor-fields-odd>>;\n}\n\n.tc-edit-fields > tbody > .tc-edit-field:nth-child(even) {\n\tbackground-color: <<colour tiddler-editor-fields-even>>;\n}\n\n.tc-edit-field-name {\n\ttext-align: right;\n}\n\n.tc-edit-field-value input {\n\twidth: 100%;\n}\n\n.tc-edit-field-remove {\n}\n\n.tc-edit-field-remove svg {\n\theight: 1em;\n\twidth: 1em;\n\tfill: <<colour muted-foreground>>;\n\tvertical-align: middle;\n}\n\n.tc-edit-field-add-name {\n\tdisplay: inline-block;\n\twidth: 15%;\n}\n\n.tc-edit-field-add-value {\n\tdisplay: inline-block;\n\twidth: 40%;\n}\n\n.tc-edit-field-add-button {\n\tdisplay: inline-block;\n\twidth: 10%;\n}\n\n/*\n** Storyview Classes\n*/\n\n.tc-storyview-zoomin-tiddler {\n\tposition: absolute;\n\tdisplay: block;\n\twidth: 100%;\n}\n\n@media (min-width: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}}) {\n\n\t.tc-storyview-zoomin-tiddler {\n\t\twidth: calc(100% - 84px);\n\t}\n\n}\n\n/*\n** Dropdowns\n*/\n\n.tc-btn-dropdown {\n\ttext-align: left;\n}\n\n.tc-btn-dropdown svg, .tc-btn-dropdown img {\n\theight: 1em;\n\twidth: 1em;\n\tfill: <<colour muted-foreground>>;\n}\n\n.tc-drop-down-wrapper {\n\tposition: relative;\n}\n\n.tc-drop-down {\n\tmin-width: 380px;\n\tborder: 1px solid <<colour dropdown-border>>;\n\tbackground-color: <<colour dropdown-background>>;\n\tpadding: 7px 0 7px 0;\n\tmargin: 4px 0 0 0;\n\twhite-space: nowrap;\n\ttext-shadow: none;\n\tline-height: 1.4;\n}\n\n.tc-drop-down .tc-drop-down {\n\tmargin-left: 14px;\n}\n\n.tc-drop-down button svg, .tc-drop-down a svg {\n\tfill: <<colour foreground>>;\n}\n\n.tc-drop-down button.tc-btn-invisible:hover svg {\n\tfill: <<colour foreground>>;\n}\n\n.tc-drop-down p {\n\tpadding: 0 14px 0 14px;\n}\n\n.tc-drop-down svg {\n\twidth: 1em;\n\theight: 1em;\n}\n\n.tc-drop-down img {\n\twidth: 1em;\n}\n\n.tc-drop-down a, .tc-drop-down button {\n\tdisplay: block;\n\tpadding: 0 14px 0 14px;\n\twidth: 100%;\n\ttext-align: left;\n\tcolor: <<colour foreground>>;\n\tline-height: 1.4;\n}\n\n.tc-drop-down .tc-tab-set .tc-tab-buttons button {\n\tdisplay: inline-block;\n width: auto;\n margin-bottom: 0px;\n border-bottom-left-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.tc-drop-down .tc-prompt {\n\tpadding: 0 14px;\n}\n\n.tc-drop-down .tc-chooser {\n\tborder: none;\n}\n\n.tc-drop-down .tc-chooser .tc-swatches-horiz {\n\tfont-size: 0.4em;\n\tpadding-left: 1.2em;\n}\n\n.tc-drop-down .tc-file-input-wrapper {\n\twidth: 100%;\n}\n\n.tc-drop-down .tc-file-input-wrapper button {\n\tcolor: <<colour foreground>>;\n}\n\n.tc-drop-down a:hover, .tc-drop-down button:hover, .tc-drop-down .tc-file-input-wrapper:hover button {\n\tcolor: <<colour tiddler-link-background>>;\n\tbackground-color: <<colour tiddler-link-foreground>>;\n\ttext-decoration: none;\n}\n\n.tc-drop-down .tc-tab-buttons button {\n\tbackground-color: <<colour dropdown-tab-background>>;\n}\n\n.tc-drop-down .tc-tab-buttons button.tc-tab-selected {\n\tbackground-color: <<colour dropdown-tab-background-selected>>;\n\tborder-bottom: 1px solid <<colour dropdown-tab-background-selected>>;\n}\n\n.tc-drop-down-bullet {\n\tdisplay: inline-block;\n\twidth: 0.5em;\n}\n\n.tc-drop-down .tc-tab-contents a {\n\tpadding: 0 0.5em 0 0.5em;\n}\n\n.tc-block-dropdown-wrapper {\n\tposition: relative;\n}\n\n.tc-block-dropdown {\n\tposition: absolute;\n\tmin-width: 220px;\n\tborder: 1px solid <<colour dropdown-border>>;\n\tbackground-color: <<colour dropdown-background>>;\n\tpadding: 7px 0;\n\tmargin: 4px 0 0 0;\n\twhite-space: nowrap;\n\tz-index: 1000;\n\ttext-shadow: none;\n}\n\n.tc-block-dropdown.tc-search-drop-down {\n\tmargin-left: -12px;\n}\n\n.tc-block-dropdown a {\n\tdisplay: block;\n\tpadding: 4px 14px 4px 14px;\n}\n\n.tc-block-dropdown.tc-search-drop-down a {\n\tdisplay: block;\n\tpadding: 0px 10px 0px 10px;\n}\n\n.tc-drop-down .tc-dropdown-item-plain,\n.tc-block-dropdown .tc-dropdown-item-plain {\n\tpadding: 4px 14px 4px 7px;\n}\n\n.tc-drop-down .tc-dropdown-item,\n.tc-block-dropdown .tc-dropdown-item {\n\tpadding: 4px 14px 4px 7px;\n\tcolor: <<colour muted-foreground>>;\n}\n\n.tc-block-dropdown a:hover {\n\tcolor: <<colour tiddler-link-background>>;\n\tbackground-color: <<colour tiddler-link-foreground>>;\n\ttext-decoration: none;\n}\n\n.tc-search-results {\n\tpadding: 0 7px 0 7px;\n}\n\n.tc-image-chooser, .tc-colour-chooser {\n\twhite-space: normal;\n}\n\n.tc-image-chooser a,\n.tc-colour-chooser a {\n\tdisplay: inline-block;\n\tvertical-align: top;\n\ttext-align: center;\n\tposition: relative;\n}\n\n.tc-image-chooser a {\n\tborder: 1px solid <<colour muted-foreground>>;\n\tpadding: 2px;\n\tmargin: 2px;\n\twidth: 4em;\n\theight: 4em;\n}\n\n.tc-colour-chooser a {\n\tpadding: 3px;\n\twidth: 2em;\n\theight: 2em;\n\tvertical-align: middle;\n}\n\n.tc-image-chooser a:hover,\n.tc-colour-chooser a:hover {\n\tbackground: <<colour primary>>;\n\tpadding: 0px;\n\tborder: 3px solid <<colour primary>>;\n}\n\n.tc-image-chooser a svg,\n.tc-image-chooser a img {\n\tdisplay: inline-block;\n\twidth: auto;\n\theight: auto;\n\tmax-width: 3.5em;\n\tmax-height: 3.5em;\n\tposition: absolute;\n\ttop: 0;\n\tbottom: 0;\n\tleft: 0;\n\tright: 0;\n\tmargin: auto;\n}\n\n/*\n** Modals\n*/\n\n.tc-modal-wrapper {\n\tposition: fixed;\n\toverflow: auto;\n\toverflow-y: scroll;\n\ttop: 0;\n\tright: 0;\n\tbottom: 0;\n\tleft: 0;\n\tz-index: 900;\n}\n\n.tc-modal-backdrop {\n\tposition: fixed;\n\ttop: 0;\n\tright: 0;\n\tbottom: 0;\n\tleft: 0;\n\tz-index: 1000;\n\tbackground-color: <<colour modal-backdrop>>;\n}\n\n.tc-modal {\n\tz-index: 1100;\n\tbackground-color: <<colour modal-background>>;\n\tborder: 1px solid <<colour modal-border>>;\n}\n\n@media (max-width: 55em) {\n\t.tc-modal {\n\t\tposition: fixed;\n\t\ttop: 1em;\n\t\tleft: 1em;\n\t\tright: 1em;\n\t}\n\n\t.tc-modal-body {\n\t\toverflow-y: auto;\n\t\tmax-height: 400px;\n\t\tmax-height: 60vh;\n\t}\n}\n\n@media (min-width: 55em) {\n\t.tc-modal {\n\t\tposition: fixed;\n\t\ttop: 2em;\n\t\tleft: 25%;\n\t\twidth: 50%;\n\t}\n\n\t.tc-modal-body {\n\t\toverflow-y: auto;\n\t\tmax-height: 400px;\n\t\tmax-height: 60vh;\n\t}\n}\n\n.tc-modal-header {\n\tpadding: 9px 15px;\n\tborder-bottom: 1px solid <<colour modal-header-border>>;\n}\n\n.tc-modal-header h3 {\n\tmargin: 0;\n\tline-height: 30px;\n}\n\n.tc-modal-header img, .tc-modal-header svg {\n\twidth: 1em;\n\theight: 1em;\n}\n\n.tc-modal-body {\n\tpadding: 15px;\n}\n\n.tc-modal-footer {\n\tpadding: 14px 15px 15px;\n\tmargin-bottom: 0;\n\ttext-align: right;\n\tbackground-color: <<colour modal-footer-background>>;\n\tborder-top: 1px solid <<colour modal-footer-border>>;\n}\n\n/*\n** Notifications\n*/\n\n.tc-notification {\n\tposition: fixed;\n\ttop: 14px;\n\tright: 42px;\n\tz-index: 1300;\n\tmax-width: 280px;\n\tpadding: 0 14px 0 14px;\n\tbackground-color: <<colour notification-background>>;\n\tborder: 1px solid <<colour notification-border>>;\n}\n\n/*\n** Tabs\n*/\n\n.tc-tab-set.tc-vertical {\n\tdisplay: -webkit-flex;\n\tdisplay: flex;\n}\n\n.tc-tab-buttons {\n\tfont-size: 0.85em;\n\tpadding-top: 1em;\n\tmargin-bottom: -2px;\n}\n\n.tc-tab-buttons.tc-vertical {\n\tz-index: 100;\n\tdisplay: block;\n\tpadding-top: 14px;\n\tvertical-align: top;\n\ttext-align: right;\n\tmargin-bottom: inherit;\n\tmargin-right: -1px;\n\tmax-width: 33%;\n\t-webkit-flex: 0 0 auto;\n\tflex: 0 0 auto;\n}\n\n.tc-tab-buttons button.tc-tab-selected {\n\tcolor: <<colour tab-foreground-selected>>;\n\tbackground-color: <<colour tab-background-selected>>;\n\tborder-left: 1px solid <<colour tab-border-selected>>;\n\tborder-top: 1px solid <<colour tab-border-selected>>;\n\tborder-right: 1px solid <<colour tab-border-selected>>;\n}\n\n.tc-tab-buttons button {\n\tcolor: <<colour tab-foreground>>;\n\tpadding: 3px 5px 3px 5px;\n\tmargin-right: 0.3em;\n\tfont-weight: 300;\n\tborder: none;\n\tbackground: inherit;\n\tbackground-color: <<colour tab-background>>;\n\tborder-left: 1px solid <<colour tab-border>>;\n\tborder-top: 1px solid <<colour tab-border>>;\n\tborder-right: 1px solid <<colour tab-border>>;\n\tborder-top-left-radius: 2px;\n\tborder-top-right-radius: 2px;\n\tborder-bottom-left-radius: 0;\n\tborder-bottom-right-radius: 0;\n}\n\n.tc-tab-buttons.tc-vertical button {\n\tdisplay: block;\n\twidth: 100%;\n\tmargin-top: 3px;\n\tmargin-right: 0;\n\ttext-align: right;\n\tbackground-color: <<colour tab-background>>;\n\tborder-left: 1px solid <<colour tab-border>>;\n\tborder-bottom: 1px solid <<colour tab-border>>;\n\tborder-right: none;\n\tborder-top-left-radius: 2px;\n\tborder-bottom-left-radius: 2px;\n\tborder-top-right-radius: 0;\n\tborder-bottom-right-radius: 0;\n}\n\n.tc-tab-buttons.tc-vertical button.tc-tab-selected {\n\tbackground-color: <<colour tab-background-selected>>;\n\tborder-right: 1px solid <<colour tab-background-selected>>;\n}\n\n.tc-tab-divider {\n\tborder-top: 1px solid <<colour tab-divider>>;\n}\n\n.tc-tab-divider.tc-vertical {\n\tdisplay: none;\n}\n\n.tc-tab-content {\n\tmargin-top: 14px;\n}\n\n.tc-tab-content.tc-vertical {\n word-break: break-word;\n\tdisplay: inline-block;\n\tvertical-align: top;\n\tpadding-top: 0;\n\tpadding-left: 14px;\n\tborder-left: 1px solid <<colour tab-border>>;\n\t-webkit-flex: 1 0 70%;\n\tflex: 1 0 70%;\n}\n\n.tc-sidebar-lists .tc-tab-buttons {\n\tmargin-bottom: -1px;\n}\n\n.tc-sidebar-lists .tc-tab-buttons button.tc-tab-selected {\n\tbackground-color: <<colour sidebar-tab-background-selected>>;\n\tcolor: <<colour sidebar-tab-foreground-selected>>;\n\tborder-left: 1px solid <<colour sidebar-tab-border-selected>>;\n\tborder-top: 1px solid <<colour sidebar-tab-border-selected>>;\n\tborder-right: 1px solid <<colour sidebar-tab-border-selected>>;\n}\n\n.tc-sidebar-lists .tc-tab-buttons button {\n\tbackground-color: <<colour sidebar-tab-background>>;\n\tcolor: <<colour sidebar-tab-foreground>>;\n\tborder-left: 1px solid <<colour sidebar-tab-border>>;\n\tborder-top: 1px solid <<colour sidebar-tab-border>>;\n\tborder-right: 1px solid <<colour sidebar-tab-border>>;\n}\n\n.tc-sidebar-lists .tc-tab-divider {\n\tborder-top: 1px solid <<colour sidebar-tab-divider>>;\n}\n\n.tc-more-sidebar > .tc-tab-set > .tc-tab-buttons > button {\n\tdisplay: block;\n\twidth: 100%;\n\tbackground-color: <<colour sidebar-tab-background>>;\n\tborder-top: none;\n\tborder-left: none;\n\tborder-bottom: none;\n\tborder-right: 1px solid #ccc;\n\tmargin-bottom: inherit;\n}\n\n.tc-more-sidebar > .tc-tab-set > .tc-tab-buttons > button.tc-tab-selected {\n\tbackground-color: <<colour sidebar-tab-background-selected>>;\n\tborder: none;\n}\n\n/*\n** Manager\n*/\n\n.tc-manager-wrapper {\n\t\n}\n\n.tc-manager-controls {\n\t\n}\n\n.tc-manager-control {\n\tmargin: 0.5em 0;\n}\n\n.tc-manager-list {\n\twidth: 100%;\n\tborder-top: 1px solid <<colour muted-foreground>>;\n\tborder-left: 1px solid <<colour muted-foreground>>;\n\tborder-right: 1px solid <<colour muted-foreground>>;\n}\n\n.tc-manager-list-item {\n\n}\n\n.tc-manager-list-item-heading {\n display: block;\n width: 100%;\n text-align: left;\t\n\tborder-bottom: 1px solid <<colour muted-foreground>>;\n\tpadding: 3px;\n}\n\n.tc-manager-list-item-heading-selected {\n\tfont-weight: bold;\n\tcolor: <<colour background>>;\n\tfill: <<colour background>>;\n\tbackground-color: <<colour foreground>>;\n}\n\n.tc-manager-list-item-heading:hover {\n\tbackground: <<colour primary>>;\n\tcolor: <<colour background>>;\n}\n\n.tc-manager-list-item-content {\n\tdisplay: flex;\n}\n\n.tc-manager-list-item-content-sidebar {\n flex: 1 0;\n background: <<colour tiddler-editor-background>>;\n border-right: 0.5em solid <<colour muted-foreground>>;\n border-bottom: 0.5em solid <<colour muted-foreground>>;\n white-space: nowrap;\n}\n\n.tc-manager-list-item-content-item-heading {\n\tdisplay: block;\n\twidth: 100%;\n\ttext-align: left;\n background: <<colour muted-foreground>>;\n\ttext-transform: uppercase;\n\tfont-size: 0.6em;\n\tfont-weight: bold;\n padding: 0.5em 0 0.5em 0;\n}\n\n.tc-manager-list-item-content-item-body {\n\tpadding: 0 0.5em 0 0.5em;\n}\n\n.tc-manager-list-item-content-item-body > pre {\n\tmargin: 0.5em 0 0.5em 0;\n\tborder: none;\n\tbackground: inherit;\n}\n\n.tc-manager-list-item-content-tiddler {\n flex: 3 1;\n border-left: 0.5em solid <<colour muted-foreground>>;\n border-right: 0.5em solid <<colour muted-foreground>>;\n border-bottom: 0.5em solid <<colour muted-foreground>>;\n}\n\n.tc-manager-list-item-content-item-body > table {\n\tborder: none;\n\tpadding: 0;\n\tmargin: 0;\n}\n\n.tc-manager-list-item-content-item-body > table td {\n\tborder: none;\n}\n\n.tc-manager-icon-editor > button {\n\twidth: 100%;\n}\n\n.tc-manager-icon-editor > button > svg,\n.tc-manager-icon-editor > button > button {\n\twidth: 100%;\n\theight: auto;\n}\n\n/*\n** Alerts\n*/\n\n.tc-alerts {\n\tposition: fixed;\n\ttop: 0;\n\tleft: 0;\n\tmax-width: 500px;\n\tz-index: 20000;\n}\n\n.tc-alert {\n\tposition: relative;\n\tmargin: 28px;\n\tpadding: 14px 14px 14px 14px;\n\tborder: 2px solid <<colour alert-border>>;\n\tbackground-color: <<colour alert-background>>;\n}\n\n.tc-alert-toolbar {\n\tposition: absolute;\n\ttop: 14px;\n\tright: 14px;\n}\n\n.tc-alert-toolbar svg {\n\tfill: <<colour alert-muted-foreground>>;\n}\n\n.tc-alert-subtitle {\n\tcolor: <<colour alert-muted-foreground>>;\n\tfont-weight: bold;\n}\n\n.tc-alert-highlight {\n\tcolor: <<colour alert-highlight>>;\n}\n\n@media (min-width: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}}) {\n\n\t.tc-static-alert {\n\t\tposition: relative;\n\t}\n\n\t.tc-static-alert-inner {\n\t\tposition: absolute;\n\t\tz-index: 100;\n\t}\n\n}\n\n.tc-static-alert-inner {\n\tpadding: 0 2px 2px 42px;\n\tcolor: <<colour static-alert-foreground>>;\n}\n\n/*\n** Floating drafts list\n*/\n\n.tc-drafts-list {\n\tz-index: 2000;\n\tposition: fixed;\n\tfont-size: 0.8em;\n\tleft: 0;\n\tbottom: 0;\n}\n\n.tc-drafts-list a {\n\tmargin: 0 0.5em;\n\tpadding: 4px 4px;\n\tborder-top-left-radius: 4px;\n\tborder-top-right-radius: 4px;\n\tborder: 1px solid <<colour background>>;\n\tborder-bottom-none;\n\tbackground: <<colour dirty-indicator>>;\n\tcolor: <<colour background>>;\n\tfill: <<colour background>>;\n}\n\n.tc-drafts-list a:hover {\n\ttext-decoration: none;\n\tbackground: <<colour foreground>>;\n\tcolor: <<colour background>>;\n\tfill: <<colour background>>;\n}\n\n.tc-drafts-list a svg {\n\twidth: 1em;\n\theight: 1em;\n\tvertical-align: text-bottom;\n}\n\n/*\n** Control panel\n*/\n\n.tc-control-panel td {\n\tpadding: 4px;\n}\n\n.tc-control-panel table, .tc-control-panel table input, .tc-control-panel table textarea {\n\twidth: 100%;\n}\n\n.tc-plugin-info {\n\tdisplay: block;\n\tborder: 1px solid <<colour muted-foreground>>;\n\tbackground-colour: <<colour background>>;\n\tmargin: 0.5em 0 0.5em 0;\n\tpadding: 4px;\n}\n\n.tc-plugin-info-disabled {\n\tbackground: -webkit-repeating-linear-gradient(45deg, #ff0, #ff0 10px, #eee 10px, #eee 20px);\n\tbackground: repeating-linear-gradient(45deg, #ff0, #ff0 10px, #eee 10px, #eee 20px);\n}\n\n.tc-plugin-info-disabled:hover {\n\tbackground: -webkit-repeating-linear-gradient(45deg, #aa0, #aa0 10px, #888 10px, #888 20px);\n\tbackground: repeating-linear-gradient(45deg, #aa0, #aa0 10px, #888 10px, #888 20px);\n}\n\na.tc-tiddlylink.tc-plugin-info:hover {\n\ttext-decoration: none;\n\tbackground-color: <<colour primary>>;\n\tcolor: <<colour background>>;\n\tfill: <<colour foreground>>;\n}\n\na.tc-tiddlylink.tc-plugin-info:hover .tc-plugin-info > .tc-plugin-info-chunk > svg {\n\tfill: <<colour foreground>>;\n}\n\n.tc-plugin-info-chunk {\n\tdisplay: inline-block;\n\tvertical-align: middle;\n}\n\n.tc-plugin-info-chunk h1 {\n\tfont-size: 1em;\n\tmargin: 2px 0 2px 0;\n}\n\n.tc-plugin-info-chunk h2 {\n\tfont-size: 0.8em;\n\tmargin: 2px 0 2px 0;\n}\n\n.tc-plugin-info-chunk div {\n\tfont-size: 0.7em;\n\tmargin: 2px 0 2px 0;\n}\n\n.tc-plugin-info:hover > .tc-plugin-info-chunk > img, .tc-plugin-info:hover > .tc-plugin-info-chunk > svg {\n\twidth: 2em;\n\theight: 2em;\n\tfill: <<colour foreground>>;\n}\n\n.tc-plugin-info > .tc-plugin-info-chunk > img, .tc-plugin-info > .tc-plugin-info-chunk > svg {\n\twidth: 2em;\n\theight: 2em;\n\tfill: <<colour muted-foreground>>;\n}\n\n.tc-plugin-info.tc-small-icon > .tc-plugin-info-chunk > img, .tc-plugin-info.tc-small-icon > .tc-plugin-info-chunk > svg {\n\twidth: 1em;\n\theight: 1em;\n}\n\n.tc-plugin-info-dropdown {\n\tborder: 1px solid <<colour muted-foreground>>;\n\tmargin-top: -8px;\n}\n\n.tc-plugin-info-dropdown-message {\n\tbackground: <<colour message-background>>;\n\tpadding: 0.5em 1em 0.5em 1em;\n\tfont-weight: bold;\n\tfont-size: 0.8em;\n}\n\n.tc-plugin-info-dropdown-body {\n\tpadding: 1em 1em 1em 1em;\n}\n\n.tc-check-list {\n\tline-height: 2em;\n}\n\n.tc-check-list .tc-image-button {\n\theight: 1.5em;\n}\n\n/*\n** Message boxes\n*/\n\n.tc-message-box {\n\tborder: 1px solid <<colour message-border>>;\n\tbackground: <<colour message-background>>;\n\tpadding: 0px 21px 0px 21px;\n\tfont-size: 12px;\n\tline-height: 18px;\n\tcolor: <<colour message-foreground>>;\n}\n\n.tc-message-box svg {\n\twidth: 1em;\n\theight: 1em;\n vertical-align: text-bottom;\n}\n\n/*\n** Pictures\n*/\n\n.tc-bordered-image {\n\tborder: 1px solid <<colour muted-foreground>>;\n\tpadding: 5px;\n\tmargin: 5px;\n}\n\n/*\n** Floats\n*/\n\n.tc-float-right {\n\tfloat: right;\n}\n\n/*\n** Chooser\n*/\n\n.tc-chooser {\n\tborder-right: 1px solid <<colour table-header-background>>;\n\tborder-left: 1px solid <<colour table-header-background>>;\n}\n\n\n.tc-chooser-item {\n\tborder-bottom: 1px solid <<colour table-header-background>>;\n\tborder-top: 1px solid <<colour table-header-background>>;\n\tpadding: 2px 4px 2px 14px;\n}\n\n.tc-drop-down .tc-chooser-item {\n\tpadding: 2px;\n}\n\n.tc-chosen,\n.tc-chooser-item:hover {\n\tbackground-color: <<colour table-header-background>>;\n\tborder-color: <<colour table-footer-background>>;\n}\n\n.tc-chosen .tc-tiddlylink {\n\tcursor:default;\n}\n\n.tc-chooser-item .tc-tiddlylink {\n\tdisplay: block;\n\ttext-decoration: none;\n\tbackground-color: transparent;\n}\n\n.tc-chooser-item:hover .tc-tiddlylink:hover {\n\ttext-decoration: none;\n}\n\n.tc-drop-down .tc-chosen .tc-tiddlylink,\n.tc-drop-down .tc-chooser-item .tc-tiddlylink:hover {\n\tcolor: <<colour foreground>>;\n}\n\n.tc-chosen > .tc-tiddlylink:before {\n\tmargin-left: -10px;\n\tposition: relative;\n\tcontent: \"» \";\n}\n\n.tc-chooser-item svg,\n.tc-chooser-item img{\n\twidth: 1em;\n\theight: 1em;\n\tvertical-align: middle;\n}\n\n.tc-language-chooser .tc-image-button img {\n\twidth: 2em;\n\tvertical-align: -0.15em;\n}\n\n/*\n** Palette swatches\n*/\n\n.tc-swatches-horiz {\n}\n\n.tc-swatches-horiz .tc-swatch {\n\tdisplay: inline-block;\n}\n\n.tc-swatch {\n\twidth: 2em;\n\theight: 2em;\n\tmargin: 0.4em;\n\tborder: 1px solid #888;\n}\n\n/*\n** Table of contents\n*/\n\n.tc-sidebar-lists .tc-table-of-contents {\n\twhite-space: nowrap;\n}\n\n.tc-table-of-contents button {\n\tcolor: <<colour sidebar-foreground>>;\n}\n\n.tc-table-of-contents svg {\n\twidth: 0.7em;\n\theight: 0.7em;\n\tvertical-align: middle;\n\tfill: <<colour sidebar-foreground>>;\n}\n\n.tc-table-of-contents ol {\n\tlist-style-type: none;\n\tpadding-left: 0;\n}\n\n.tc-table-of-contents ol ol {\n\tpadding-left: 1em;\n}\n\n.tc-table-of-contents li {\n\tfont-size: 1.0em;\n\tfont-weight: bold;\n}\n\n.tc-table-of-contents li a {\n\tfont-weight: bold;\n}\n\n.tc-table-of-contents li li {\n\tfont-size: 0.95em;\n\tfont-weight: normal;\n\tline-height: 1.4;\n}\n\n.tc-table-of-contents li li a {\n\tfont-weight: normal;\n}\n\n.tc-table-of-contents li li li {\n\tfont-size: 0.95em;\n\tfont-weight: 200;\n\tline-height: 1.5;\n}\n\n.tc-table-of-contents li li li li {\n\tfont-size: 0.95em;\n\tfont-weight: 200;\n}\n\n.tc-tabbed-table-of-contents {\n\tdisplay: -webkit-flex;\n\tdisplay: flex;\n}\n\n.tc-tabbed-table-of-contents .tc-table-of-contents {\n\tz-index: 100;\n\tdisplay: inline-block;\n\tpadding-left: 1em;\n\tmax-width: 50%;\n\t-webkit-flex: 0 0 auto;\n\tflex: 0 0 auto;\n\tbackground: <<colour tab-background>>;\n\tborder-left: 1px solid <<colour tab-border>>;\n\tborder-top: 1px solid <<colour tab-border>>;\n\tborder-bottom: 1px solid <<colour tab-border>>;\n}\n\n.tc-tabbed-table-of-contents .tc-table-of-contents .toc-item > a,\n.tc-tabbed-table-of-contents .tc-table-of-contents .toc-item-selected > a {\n\tdisplay: block;\n\tpadding: 0.12em 1em 0.12em 0.25em;\n}\n\n.tc-tabbed-table-of-contents .tc-table-of-contents .toc-item > a {\n\tborder-top: 1px solid <<colour tab-background>>;\n\tborder-left: 1px solid <<colour tab-background>>;\n\tborder-bottom: 1px solid <<colour tab-background>>;\n}\n\n.tc-tabbed-table-of-contents .tc-table-of-contents .toc-item > a:hover {\n\ttext-decoration: none;\n\tborder-top: 1px solid <<colour tab-border>>;\n\tborder-left: 1px solid <<colour tab-border>>;\n\tborder-bottom: 1px solid <<colour tab-border>>;\n\tbackground: <<colour tab-border>>;\n}\n\n.tc-tabbed-table-of-contents .tc-table-of-contents .toc-item-selected > a {\n\tborder-top: 1px solid <<colour tab-border>>;\n\tborder-left: 1px solid <<colour tab-border>>;\n\tborder-bottom: 1px solid <<colour tab-border>>;\n\tbackground: <<colour background>>;\n\tmargin-right: -1px;\n}\n\n.tc-tabbed-table-of-contents .tc-table-of-contents .toc-item-selected > a:hover {\n\ttext-decoration: none;\n}\n\n.tc-tabbed-table-of-contents .tc-tabbed-table-of-contents-content {\n\tdisplay: inline-block;\n\tvertical-align: top;\n\tpadding-left: 1.5em;\n\tpadding-right: 1.5em;\n\tborder: 1px solid <<colour tab-border>>;\n\t-webkit-flex: 1 0 50%;\n\tflex: 1 0 50%;\n}\n\n/*\n** Dirty indicator\n*/\n\nbody.tc-dirty span.tc-dirty-indicator, body.tc-dirty span.tc-dirty-indicator svg {\n\tfill: <<colour dirty-indicator>>;\n\tcolor: <<colour dirty-indicator>>;\n}\n\n/*\n** File inputs\n*/\n\n.tc-file-input-wrapper {\n\tposition: relative;\n\toverflow: hidden;\n\tdisplay: inline-block;\n\tvertical-align: middle;\n}\n\n.tc-file-input-wrapper input[type=file] {\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tright: 0;\n\tbottom: 0;\n\tfont-size: 999px;\n\tmax-width: 100%;\n\tmax-height: 100%;\n\tfilter: alpha(opacity=0);\n\topacity: 0;\n\toutline: none;\n\tbackground: white;\n\tcursor: pointer;\n\tdisplay: inline-block;\n}\n\n/*\n** Thumbnail macros\n*/\n\n.tc-thumbnail-wrapper {\n\tposition: relative;\n\tdisplay: inline-block;\n\tmargin: 6px;\n\tvertical-align: top;\n}\n\n.tc-thumbnail-right-wrapper {\n\tfloat:right;\n\tmargin: 0.5em 0 0.5em 0.5em;\n}\n\n.tc-thumbnail-image {\n\ttext-align: center;\n\toverflow: hidden;\n\tborder-radius: 3px;\n}\n\n.tc-thumbnail-image svg,\n.tc-thumbnail-image img {\n\tfilter: alpha(opacity=1);\n\topacity: 1;\n\tmin-width: 100%;\n\tmin-height: 100%;\n\tmax-width: 100%;\n}\n\n.tc-thumbnail-wrapper:hover .tc-thumbnail-image svg,\n.tc-thumbnail-wrapper:hover .tc-thumbnail-image img {\n\tfilter: alpha(opacity=0.8);\n\topacity: 0.8;\n}\n\n.tc-thumbnail-background {\n\tposition: absolute;\n\tborder-radius: 3px;\n}\n\n.tc-thumbnail-icon svg,\n.tc-thumbnail-icon img {\n\twidth: 3em;\n\theight: 3em;\n\t<<filter \"drop-shadow(2px 2px 4px rgba(0,0,0,0.3))\">>\n}\n\n.tc-thumbnail-wrapper:hover .tc-thumbnail-icon svg,\n.tc-thumbnail-wrapper:hover .tc-thumbnail-icon img {\n\tfill: #fff;\n\t<<filter \"drop-shadow(3px 3px 4px rgba(0,0,0,0.6))\">>\n}\n\n.tc-thumbnail-icon {\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tright: 0;\n\tbottom: 0;\n\tdisplay: -webkit-flex;\n\t-webkit-align-items: center;\n\t-webkit-justify-content: center;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n}\n\n.tc-thumbnail-caption {\n\tposition: absolute;\n\tbackground-color: #777;\n\tcolor: #fff;\n\ttext-align: center;\n\tbottom: 0;\n\twidth: 100%;\n\tfilter: alpha(opacity=0.9);\n\topacity: 0.9;\n\tline-height: 1.4;\n\tborder-bottom-left-radius: 3px;\n\tborder-bottom-right-radius: 3px;\n}\n\n.tc-thumbnail-wrapper:hover .tc-thumbnail-caption {\n\tfilter: alpha(opacity=1);\n\topacity: 1;\n}\n\n/*\n** Diffs\n*/\n\n.tc-diff-equal {\n\tbackground-color: <<colour diff-equal-background>>;\n\tcolor: <<colour diff-equal-foreground>>;\n}\n\n.tc-diff-insert {\n\tbackground-color: <<colour diff-insert-background>>;\n\tcolor: <<colour diff-insert-foreground>>;\n}\n\n.tc-diff-delete {\n\tbackground-color: <<colour diff-delete-background>>;\n\tcolor: <<colour diff-delete-foreground>>;\n}\n\n.tc-diff-invisible {\n\tbackground-color: <<colour diff-invisible-background>>;\n\tcolor: <<colour diff-invisible-foreground>>;\n}\n\n.tc-diff-tiddlers th {\n\ttext-align: right;\n\tbackground: <<colour background>>;\n\tfont-weight: normal;\n\tfont-style: italic;\n}\n\n.tc-diff-tiddlers pre {\n margin: 0;\n padding: 0;\n border: none;\n background: none;\n}\n\n/*\n** Errors\n*/\n\n.tc-error {\n\tbackground: #f00;\n\tcolor: #fff;\n}\n\n/*\n** Tree macro\n*/\n\n.tc-tree div {\n \tpadding-left: 14px;\n}\n\n.tc-tree ol {\n \tlist-style-type: none;\n \tpadding-left: 0;\n \tmargin-top: 0;\n}\n\n.tc-tree ol ol {\n \tpadding-left: 1em; \n}\n\n.tc-tree button { \n \tcolor: #acacac;\n}\n\n.tc-tree svg {\n \tfill: #acacac;\n}\n\n.tc-tree span svg {\n \twidth: 1em;\n \theight: 1em;\n \tvertical-align: baseline;\n}\n\n.tc-tree li span {\n \tcolor: lightgray;\n}\n\nselect {\n color: <<colour select-tag-foreground>>;\n background: <<colour select-tag-background>>;\n}\n\n"
},
"$:/themes/tiddlywiki/vanilla/metrics/bodyfontsize": {
"title": "$:/themes/tiddlywiki/vanilla/metrics/bodyfontsize",
"text": "15px"
},
"$:/themes/tiddlywiki/vanilla/metrics/bodylineheight": {
"title": "$:/themes/tiddlywiki/vanilla/metrics/bodylineheight",
"text": "22px"
},
"$:/themes/tiddlywiki/vanilla/metrics/fontsize": {
"title": "$:/themes/tiddlywiki/vanilla/metrics/fontsize",
"text": "14px"
},
"$:/themes/tiddlywiki/vanilla/metrics/lineheight": {
"title": "$:/themes/tiddlywiki/vanilla/metrics/lineheight",
"text": "20px"
},
"$:/themes/tiddlywiki/vanilla/metrics/storyleft": {
"title": "$:/themes/tiddlywiki/vanilla/metrics/storyleft",
"text": "0px"
},
"$:/themes/tiddlywiki/vanilla/metrics/storytop": {
"title": "$:/themes/tiddlywiki/vanilla/metrics/storytop",
"text": "0px"
},
"$:/themes/tiddlywiki/vanilla/metrics/storyright": {
"title": "$:/themes/tiddlywiki/vanilla/metrics/storyright",
"text": "770px"
},
"$:/themes/tiddlywiki/vanilla/metrics/storywidth": {
"title": "$:/themes/tiddlywiki/vanilla/metrics/storywidth",
"text": "770px"
},
"$:/themes/tiddlywiki/vanilla/metrics/tiddlerwidth": {
"title": "$:/themes/tiddlywiki/vanilla/metrics/tiddlerwidth",
"text": "686px"
},
"$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint": {
"title": "$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint",
"text": "960px"
},
"$:/themes/tiddlywiki/vanilla/metrics/sidebarwidth": {
"title": "$:/themes/tiddlywiki/vanilla/metrics/sidebarwidth",
"text": "350px"
},
"$:/themes/tiddlywiki/vanilla/options/stickytitles": {
"title": "$:/themes/tiddlywiki/vanilla/options/stickytitles",
"text": "no"
},
"$:/themes/tiddlywiki/vanilla/options/sidebarlayout": {
"title": "$:/themes/tiddlywiki/vanilla/options/sidebarlayout",
"text": "fixed-fluid"
},
"$:/themes/tiddlywiki/vanilla/options/codewrapping": {
"title": "$:/themes/tiddlywiki/vanilla/options/codewrapping",
"text": "pre-wrap"
},
"$:/themes/tiddlywiki/vanilla/reset": {
"title": "$:/themes/tiddlywiki/vanilla/reset",
"type": "text/plain",
"text": "/*! normalize.css v3.0.0 | MIT License | git.io/normalize */\n\n/**\n * 1. Set default font family to sans-serif.\n * 2. Prevent iOS text size adjust after orientation change, without disabling\n * user zoom.\n */\n\nhtml {\n font-family: sans-serif; /* 1 */\n -ms-text-size-adjust: 100%; /* 2 */\n -webkit-text-size-adjust: 100%; /* 2 */\n}\n\n/**\n * Remove default margin.\n */\n\nbody {\n margin: 0;\n}\n\n/* HTML5 display definitions\n ========================================================================== */\n\n/**\n * Correct `block` display not defined in IE 8/9.\n */\n\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nnav,\nsection,\nsummary {\n display: block;\n}\n\n/**\n * 1. Correct `inline-block` display not defined in IE 8/9.\n * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.\n */\n\naudio,\ncanvas,\nprogress,\nvideo {\n display: inline-block; /* 1 */\n vertical-align: baseline; /* 2 */\n}\n\n/**\n * Prevent modern browsers from displaying `audio` without controls.\n * Remove excess height in iOS 5 devices.\n */\n\naudio:not([controls]) {\n display: none;\n height: 0;\n}\n\n/**\n * Address `[hidden]` styling not present in IE 8/9.\n * Hide the `template` element in IE, Safari, and Firefox < 22.\n */\n\n[hidden],\ntemplate {\n display: none;\n}\n\n/* Links\n ========================================================================== */\n\n/**\n * Remove the gray background color from active links in IE 10.\n */\n\na {\n background: transparent;\n}\n\n/**\n * Improve readability when focused and also mouse hovered in all browsers.\n */\n\na:active,\na:hover {\n outline: 0;\n}\n\n/* Text-level semantics\n ========================================================================== */\n\n/**\n * Address styling not present in IE 8/9, Safari 5, and Chrome.\n */\n\nabbr[title] {\n border-bottom: 1px dotted;\n}\n\n/**\n * Address style set to `bolder` in Firefox 4+, Safari 5, and Chrome.\n */\n\nb,\nstrong {\n font-weight: bold;\n}\n\n/**\n * Address styling not present in Safari 5 and Chrome.\n */\n\ndfn {\n font-style: italic;\n}\n\n/**\n * Address variable `h1` font-size and margin within `section` and `article`\n * contexts in Firefox 4+, Safari 5, and Chrome.\n */\n\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\n\n/**\n * Address styling not present in IE 8/9.\n */\n\nmark {\n background: #ff0;\n color: #000;\n}\n\n/**\n * Address inconsistent and variable font size in all browsers.\n */\n\nsmall {\n font-size: 80%;\n}\n\n/**\n * Prevent `sub` and `sup` affecting `line-height` in all browsers.\n */\n\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\n\nsup {\n top: -0.5em;\n}\n\nsub {\n bottom: -0.25em;\n}\n\n/* Embedded content\n ========================================================================== */\n\n/**\n * Remove border when inside `a` element in IE 8/9.\n */\n\nimg {\n border: 0;\n}\n\n/**\n * Correct overflow displayed oddly in IE 9.\n */\n\nsvg:not(:root) {\n overflow: hidden;\n}\n\n/* Grouping content\n ========================================================================== */\n\n/**\n * Address margin not present in IE 8/9 and Safari 5.\n */\n\nfigure {\n margin: 1em 40px;\n}\n\n/**\n * Address differences between Firefox and other browsers.\n */\n\nhr {\n -moz-box-sizing: content-box;\n box-sizing: content-box;\n height: 0;\n}\n\n/**\n * Contain overflow in all browsers.\n */\n\npre {\n overflow: auto;\n}\n\n/**\n * Address odd `em`-unit font size rendering in all browsers.\n */\n\ncode,\nkbd,\npre,\nsamp {\n font-family: monospace, monospace;\n font-size: 1em;\n}\n\n/* Forms\n ========================================================================== */\n\n/**\n * Known limitation: by default, Chrome and Safari on OS X allow very limited\n * styling of `select`, unless a `border` property is set.\n */\n\n/**\n * 1. Correct color not being inherited.\n * Known issue: affects color of disabled elements.\n * 2. Correct font properties not being inherited.\n * 3. Address margins set differently in Firefox 4+, Safari 5, and Chrome.\n */\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n color: inherit; /* 1 */\n font: inherit; /* 2 */\n margin: 0; /* 3 */\n}\n\n/**\n * Address `overflow` set to `hidden` in IE 8/9/10.\n */\n\nbutton {\n overflow: visible;\n}\n\n/**\n * Address inconsistent `text-transform` inheritance for `button` and `select`.\n * All other form control elements do not inherit `text-transform` values.\n * Correct `button` style inheritance in Firefox, IE 8+, and Opera\n * Correct `select` style inheritance in Firefox.\n */\n\nbutton,\nselect {\n text-transform: none;\n}\n\n/**\n * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`\n * and `video` controls.\n * 2. Correct inability to style clickable `input` types in iOS.\n * 3. Improve usability and consistency of cursor style between image-type\n * `input` and others.\n */\n\nbutton,\nhtml input[type=\"button\"], /* 1 */\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n -webkit-appearance: button; /* 2 */\n cursor: pointer; /* 3 */\n}\n\n/**\n * Re-set default cursor for disabled elements.\n */\n\nbutton[disabled],\nhtml input[disabled] {\n cursor: default;\n}\n\n/**\n * Remove inner padding and border in Firefox 4+.\n */\n\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n border: 0;\n padding: 0;\n}\n\n/**\n * Address Firefox 4+ setting `line-height` on `input` using `!important` in\n * the UA stylesheet.\n */\n\ninput {\n line-height: normal;\n}\n\n/**\n * It's recommended that you don't attempt to style these elements.\n * Firefox's implementation doesn't respect box-sizing, padding, or width.\n *\n * 1. Address box sizing set to `content-box` in IE 8/9/10.\n * 2. Remove excess padding in IE 8/9/10.\n */\n\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n box-sizing: border-box; /* 1 */\n padding: 0; /* 2 */\n}\n\n/**\n * Fix the cursor style for Chrome's increment/decrement buttons. For certain\n * `font-size` values of the `input`, it causes the cursor style of the\n * decrement button to change from `default` to `text`.\n */\n\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n/**\n * 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome.\n * 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome\n * (include `-moz` to future-proof).\n */\n\ninput[type=\"search\"] {\n -webkit-appearance: textfield; /* 1 */\n -moz-box-sizing: content-box;\n -webkit-box-sizing: content-box; /* 2 */\n box-sizing: content-box;\n}\n\n/**\n * Remove inner padding and search cancel button in Safari and Chrome on OS X.\n * Safari (but not Chrome) clips the cancel button when the search input has\n * padding (and `textfield` appearance).\n */\n\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n/**\n * Define consistent border, margin, and padding.\n */\n\nfieldset {\n border: 1px solid #c0c0c0;\n margin: 0 2px;\n padding: 0.35em 0.625em 0.75em;\n}\n\n/**\n * 1. Correct `color` not being inherited in IE 8/9.\n * 2. Remove padding so people aren't caught out if they zero out fieldsets.\n */\n\nlegend {\n border: 0; /* 1 */\n padding: 0; /* 2 */\n}\n\n/**\n * Remove default vertical scrollbar in IE 8/9.\n */\n\ntextarea {\n overflow: auto;\n}\n\n/**\n * Don't inherit the `font-weight` (applied by a rule above).\n * NOTE: the default cannot safely be changed in Chrome and Safari on OS X.\n */\n\noptgroup {\n font-weight: bold;\n}\n\n/* Tables\n ========================================================================== */\n\n/**\n * Remove most spacing between table cells.\n */\n\ntable {\n border-collapse: collapse;\n border-spacing: 0;\n}\n\ntd,\nth {\n padding: 0;\n}\n"
},
"$:/themes/tiddlywiki/vanilla/settings/fontfamily": {
"title": "$:/themes/tiddlywiki/vanilla/settings/fontfamily",
"text": "-apple-system, BlinkMacSystemFont, \"Segoe UI\", Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\""
},
"$:/themes/tiddlywiki/vanilla/settings/codefontfamily": {
"title": "$:/themes/tiddlywiki/vanilla/settings/codefontfamily",
"text": "\"SFMono-Regular\",Consolas,\"Liberation Mono\",Menlo,Courier,monospace"
},
"$:/themes/tiddlywiki/vanilla/settings/backgroundimageattachment": {
"title": "$:/themes/tiddlywiki/vanilla/settings/backgroundimageattachment",
"text": "fixed"
},
"$:/themes/tiddlywiki/vanilla/settings/backgroundimagesize": {
"title": "$:/themes/tiddlywiki/vanilla/settings/backgroundimagesize",
"text": "auto"
},
"$:/themes/tiddlywiki/vanilla/sticky": {
"title": "$:/themes/tiddlywiki/vanilla/sticky",
"text": "<$reveal state=\"$:/themes/tiddlywiki/vanilla/options/stickytitles\" type=\"match\" text=\"yes\">\n``\n.tc-tiddler-title {\n\tposition: -webkit-sticky;\n\tposition: -moz-sticky;\n\tposition: -o-sticky;\n\tposition: -ms-sticky;\n\tposition: sticky;\n\ttop: 0px;\n\tbackground: ``<<colour tiddler-background>>``;\n\tz-index: 500;\n}\n``\n</$reveal>\n"
}
}
}
* This book is about seven pervasive myths, or mindsets, that undermine the process of learning and how we can avoid their debilitating effects in a wide variety of settings. >1. The basics must be learned so well that they become second nature. >2. Paying attention means staying focused on one thing at a time. >3. Delaying gratification is important. >4. Rote memorization is necessary in education. >5. Forgetting is a problem. >6. Intelligence is knowing "what's out there." >7. There are right and wrong answers. These myths undermine true learning. They stifle our creativity, silence our questions, and diminish our self-esteem. * The ideas offered here to loosen the grip of these debilitating myths are very simple. Their fundamental simplicity points to yet another inhibiting myth: that only a massive overhaul can give us a more effective educational system. * This book takes more of a "why-to" than a "how-to" approach. Nevertheless, the examples and experiments described implicitly suggest ways to learn mindfully. These are intended to guide our choices and to be adapted to each unique context, rather than to be followed mindlessly. * A mindful approach to any activity has three characteristics: ** the continuous creation of new categories; ** openness to new information; ** and an implicit awareness of more than one perspective. * Mindlessness, in contrast, is characterized by an entrapment in old categories; by automatic behavior that precludes attending to new signals; and by action that operates from a single perspective.
From a poem by Marvin Levine quoted at the beginning of the [[book|Authentic Happiness]]:
<html>
<table>
<tr>
<td width="25%">
//Escher got it right.//<br>//Men step down and yet rise up,//<br>//the hand is drawn by the hand it draws,//<br>//and a woman is poised//<br>//on her very own shoulders.//
</td>
<td width="25%" height="100%">
<a href="./resources/escher_ascend.jpg" target="new"><img src="./resources/escher_ascend_1.jpg" /></a>
</td>
<td width="25%" height="80%">
<a href="./resources/escher_hands.jpg" target="new"><img src="./resources/escher_hands_1.jpg" /></a>
</td>
<td width="25%" height="70%">
<a href="./resources/escher_woman.jpg" target="new"><img src="./resources/escher_woman_1.jpg" /></a>
</td>
</tr>
</table>
</html>
This strongly highlighted for me the ability we have to very differently interpret the same phenomena:
* one could, depressingly, interpret Esher's men as going nowhere, or at best deluding themselves that they go somewhere (up), but actually going down.
** Levine in the poem (decided to?) interprets it as "rising up".
* one could look at the hand drawing a hand, and be confused, baffled, "stuck" in the impossibility or paradox; something like this cannot possibly be happening in reality.
** Levine points out something that could be interpreted as a very real experience where [ext[we (or one hand) shape/define/influence others (or the other hand), which in turn shape/define/influence us, in an on-going spiral|resources/escher_hands.jpg]]. Looked at even more positively, this spiral is a continuous improvement/refinement loop, where adding details/capabilities to each drawn hand makes it more and more capable, and so on.
Another case of looking at things in different ways is the [["glass half full vs. glass half empty"|Given a glass with water up to the mid level, people from The West will either say it's half full or they'll say it's half empty. People from The East will say it's both half full and half empty. They are all right.]] example.
In the first chapter of his book //On Intelligence// (published in 2004), Jeff Hawkins writes that he wanted to enroll at MIT and study AI, in order to build intelligent machines. He found that his approach was totally different from the one prevalent at the AI Lab: I decided to apply to graduate school at the Massachusetts Institute of Technology, which was famous for its research on artificial intelligence and was conveniently located down the road. It seemed a great match. I had extensive training in computer science "check." I had a desire to build intelligent machines, "check." I wanted to first study brains to see how they worked "uh, that's a problem." This last goal, wanting to understand how brains worked, was a nonstarter in the eyes of the scientists at the MIT artificial intelligence lab. It was like running into a brick wall. MIT was the mother-ship of artificial intelligence. At the time I applied to MIT, it was home to dozens of bright people who were enthralled with the idea of programming computers to produce intelligent behavior. To these scientists, vision, language, robotics, and mathematics were just programming problems. Computers could do anything a brain could do, and more, so why constrain your thinking by the biological messiness of nature's computer? Studying brains would limit your thinking. They believed it was better to study the ultimate limits of computation as best expressed in digital computers. Their holy grail was to write computer programs that would first match and then surpass human abilities. They took an ends-justify-the-means approach; [[they were not interested in how real brains worked. Some took pride in ignoring neurobiology|Technology solutions - Learning from Nature]]. This struck me as precisely the wrong way to tackle the problem. Intuitively I felt that the artificial intelligence approach would not only fail to create programs that do what humans can do, it would not teach us what intelligence is. Computers and brains are built on completely different principles. One is programmed, one is self-learning. One has to be perfect to work at all, one is naturally flexible and tolerant of failures. One has a central processor, one has no centralized control. The list of differences goes on and on. The biggest reason I thought computers would not be intelligent is that I understood how computers worked, down to the level of the transistor physics, and this knowledge gave me a strong intuitive sense that brains and computers were fundamentally different. I couldn't prove it, but I knew it as much as one can intuitively know anything. Ultimately, I reasoned, AI might lead to useful products, but it wasn't going to build truly intelligent machines. In contrast, I wanted to understand real intelligence and perception, to study brain physiology and anatomy, to meet Francis Crick's challenge and come up with a broad framework for how the brain worked. I set my sights in particular on the neocortex the most recently developed part of the mammalian brain and the seat of intelligence. After understanding how the neocortex worked, then we could go about building intelligent machines, but not before. Unfortunately, the professors and students I met at MIT did not share my interests. They didn't believe that you needed to study real brains to understand intelligence and build intelligent machines. They told me so. In 1981 the university rejected my application. !!!The wrong approach to AI? According to Jeff Hawkins, after many years of effort, unfulfilled promises, and no unqualified successes, AI (Artificial Intelligence) started to lose its luster... ...there are still people who believe that AI's problems can be solved with faster computers, but most scientists think the entire endeavor was flawed (pg. 18) Hawkins also says (pg. 21): the ultimate defensive argument of AI is that computers could, in theory, simulate the entire brain.A computer could model all the neurons and their connections, and if it did there would be nothing to distinguish the "intelligence" of the brain from the "intelligence" of the computer simulation. Although this may be impossible in practice, I agree with it. But AI researchers don't simulate brains, and their programs are not intelligent. You can't simulate a brain without first understanding what it does. This echos something that Ray Kurzweil believes in, and wrote about in the book The Singularity is Near (2005). Update (as of June 2013): In [[a recent interview for The Atlantic magazine|http://www.theatlantic.com/magazine/archive/2013/07/the-intuition-machine/309392/]], Jeff [[Hawkins talks|http://www.theatlantic.com/technology/archive/2013/06/what-the-digital-brains-of-the-future-might-be-like/277048/]] about his new company - [[Grok|https://www.groksolutions.com/]] - working on self-learning software that continuously builds models based an an input stream of data, with the goal of making predictions/intuitions (which is the hallmark of intelligence according to Hawkins). So he is still trying to crack the intelligence nut, in a way that makes sense to me, starting with numenta and evolving into Grok^^1^^. <a href="./resources/Hawkins-Atlantic-AI.jpg" target="new"><img src="./resources/Hawkins-Atlantic-AI-small.jpg" width="25%" height="25%" /></a> ^^2^^ """ """ ---- ^^1^^ Author Robert A. Heinlein coined the term in his best-selling 1961 book Stranger in a Strange Land. In Heinlein's view, grokking is the intermingling of intelligence that necessarily affects both the observer and the observed. From the novel: >Grok means to understand so thoroughly that the observer becomes a part of the observed—to merge, blend, intermarry, lose identity in group experience. It means almost everything that we mean by religion, philosophy, and science—and it means as little to us (because of our Earthling assumptions) as color means to a blind man. > - [[from Wikipedia|http://en.wikipedia.org/wiki/Grok]] ^^2^^ From The Atlantic Magazine
!!!Definition of Technium As a word, technium is akin to the German word technik, which similarly encapsulates the grand totality of machines, methods, and engineering processes. Technium is also related to the French noun technique, used by French philosophers to mean the society and culture of tools. But neither term captures what I consider to be the essential quality of the technium: this idea of a self-reinforcing system of creation. At some point in its evolution, our system of tools and machines and ideas became so dense in feedback loops and complex interactions that it spawned a bit of independence. It began to exercise some autonomy. !!!Autonomy of Technium At first, this notion of technological independence is very hard to grasp. We are taught to think of technology first as a pile of hardware and secondly as inert stuff" that is wholly dependent on us humans. In this view, technology is only what we make. Without us, it ceases to be. It does only what we want. And that's what I believed, too, when I set out on this quest. But the more I looked at the whole system of technological invention, the more powerful and self-generating I realized it was. Its sustaining network of self-reinforcing processes and parts have given it a noticeable measure of autonomy. It may have once been as simple as an old computer program, merely parroting what we told it, but now it is more like a very complex organism that often follows its own urges. An organism or system does not need to be wholly independent to exhibit some degree of autonomy. Like an infant of any species, it can acquire increasing degrees of independence, starting from a speck of autonomy. So how do you detect autonomy? Well, we might say that an entity is autonomous if it displays any of these traits: self-repair, self-defense. self-maintenance (securing energy, disposing of waste), self-control of goals, self-improvement. The common element in all these characteristics is of course the emergence, at some level, of a self In the technium we don't have any examples of a system that displays all these traits but we have plenty of examples that display some of them. Autonomous airplane drones can I stay aloft for hours. But they don't repair themselves. Communication networks can repair themselves. But they don't reproduce themselves. We have self-reproducing computer viruses, but they don't improve themselves. !!!!! So my question (as opposed to Kevin Kelly's): Is this anthropomorphizing? While Kevin Kelly is aware of the possibility (or the accusation) that he may be anthropomorphizing, he concludes that he is not. But in my mind he is blurring the line by mixing keen observations that are evident/obvious/justified (e.g., that technology is becoming more and more part of our environment, and therefore a "force of nature", or at least a "force to be reckoned with"), with statements/observations that are not obvious at all, or at least could be interpreted in a different way (e.g., on page 16 he describes a robot being developed in Silicon Valley that seems to have human characteristics, like "its ability to find a power outlet and plug itself in" (thus showing "hunger"). Or "When you take hold of one of its arms, it is neither rigid at the joints nor limp. It responds in a supple manner, with a gentle give, as if the limb were alive. It's an uncanny sensation. Yet the robot's grip is as deliberate as yours." Or, "If you stand in front of a PR2 while it is hungry, it won't hurt you. It will backtrack and go around the building any way it can to find a plug. It's not conscious, but standing between it and its power outlet, you can clearly feel its want." I think that the author is not being careful enough in separating pure observation from human-like interpretation! This reminds me of the hard-nosed, no nonsense observation by the computer scientist ''Edsger Wybe Dijkstra'': ''The question of whether a computer can think is no more interesting than the question of whether a submarine can swim.'' !!!The Technium is "talking" When computer scientists dissect the massive rivers of traffic flowing through it (170 quadrillion chips wired together), they cannot account for the source of all the bits. Every now and then a bit is transmitted incorrectly, and while most of those mutations can be attributed to identifiable causes such as hacking. machine error, or line damage, the researchers are left with a few percent that somehow changed themselves. In other words, a small fraction of what the technium communicates originates not from any of its known human-made nodes but from the system at large. The technium is whispering to itself. !!!The Technium "wants" With the technium, want does not mean thoughtful decisions. I don't believe the technium is conscious (at this point). Its mechanical wants are not carefully considered deliberations but rather tendencies. Leanings. Urges. Trajectories. The wants of technology are closer to needs, a compulsion toward something. Just like the unconscious drift of a sea cucumber as it seeks a mate. The millions of amplifying relationships and countless circuits of influence among parts push the whole technium in certain unconscious directions. !!!The Technium as a "force of nature" The technium is now as great a force in our world as nature, and our response to the technium should be similar to our response to nature. We can't demand that technology obey us any more than we can demand that life obey us. Sometimes we should surrender to its lead and bask in its abundance, and sometimes we should try to bend its natural course to meet our own. We don't have to do everything that the technium demands, but we can learn to work with this force rather than against it.
Seligman writes in this chapter about personality traits, feelings, and authentic fulfillment: When well-being comes from engaging our strengths and virtues, our lives are imbued with authenticity. ''Feelings'' are states, momentary occurrences that need not be recurring features of personality. ''Traits'', in contrast to states, are either negative or positive ''characteristics'' that recur across time and different situations, and ''strengths and virtues'' are the positive characteristics that bring about good feeling and gratification. Traits are abiding dispositions whose exercise makes momentary feelings more likely. The negative trait of paranoia makes the momentary state of jealousy more likely, just as the positive trait of being humorous makes the state of laughing more likely. This well-being and feeling of authenticity, comes from engaging in activities that involve (in business-speak, leverage) our strengths and virtues.In the business world, it's sometimes called "playing to your strengths", and it was found that it yields strong positive business results (no wonder).
# Suffering occurs. # The cause of suffering is craving. # The possibility for ending suffering exists. # The cessation of suffering can be attained through the Noble Eightfold Path. ''The First Noble Truth - The Truth of Suffering'' The First Noble Truth simply says that suffering occurs. It does not say, Life is suffering. That suffering occurs perhaps does not seem a particularly profound statement. Suffering comes with being human. Pain is a part of the human condition. In the context of the Four Noble Truths, we can distinguish between inevitable suffering and optional suffering. Optional suffering is created when we react to our experience. The teaching of the Four Noble Truths does not promise relief from the inevitable suffering that arises out of being human. The suffering addressed by the Four Noble Truths is the suffering or stress that arises from the way we choose to relate to our experience. [[A story (about arrows)|14 - Mindfulness Of Emotions]] illustrates the difference between inevitable pain and optional suffering. The Buddha enumerated four kinds of clinging to help us understand our suffering and what we suffer about. * grasping to spiritual practices and ethics * grasping to views * grasping to a sense of self * grasping to sensual pleasure, which includes aversion to discomfort ''The Second Noble Truth - The Truth of the Cause of Suffering'' The Second Noble Truth states that what brings us off center, what causes our suffering, is craving (in Pali it literally means thirst). What causes suffering is desire (or aversion) that is driven, compulsive. Craving means both being driven toward experiences and objects, as well as feeling compelled to push them away. ''The Third Noble Truth - The Truth of the Cessation of Suffering'' The Third Noble Truth expresses the possibility of liberation, of the cessation of suffering. When we see our suffering and understand clearly how it arises out of craving, we know that freedom from suffering is possible when craving is released. But we need to be careful: We easily become attached to states such as calm, peace, joy, clarity, or radiant light states that sometime arise during meditation practice, but which are not its goal. We may believe that we need to attain them if we are to realize the Third Noble Truth. But if we remember non-clinging is the means to release, then we will be less inclined to cling to any state. Don't cling to your happiness. Don't cling to your sadness. Don't cling to any attainment. ''The Fourth Noble Truth - The Truth of the Path Leading to the Cessation of Suffering'' The Noble Eightfold Path gives us the steps that help us to create the conditions that make spiritual maturity possible. They are: 1. Right Understanding 2. Right Intention 3. Right Speech 4. Right Action 5. Right Livelihood 6. Right Effort 7. Right Mindfulness 8. Right Concentration
When Practice Makes Imperfect (as opposed to 'when practice makes //permanent//' :) >* It is interesting to consider that emergencies may often be the result of actions taken in response to previous training rather than in response to present considerations. >* When we approach a new skill, whether as adults or children, it is, by definition, a time when we know the least about it. Does it make sense to freeze our understanding of the skill before we try it out in different contexts and, at various stages, adjust it to our own strengths and experiences? Does it make sense to stick to what we first learned when that learning occurred when we were most naive? >* Most of us are not taught our skills, whether academic, athletic or artistic, by the real experts. The rules we are given to practice are based on generally accepted truths about how to perform the task and not on our individual abilities. If we mindlessly practice these skills, we are not likely to surpass our teachers. Even if we are fortunate enough to be shown how to do something by a true expert mindless practice keeps the activity from becoming our own. >* If we learn the basics but do not over-learn them, we can vary as we change or as the situation changes. >* ... experts at anything become expert in part by varying the basics. The rest of us, taught not to question, take them for granted. __On the Value of Doubt__ >The key to this new way of teaching is based on an appreciation of both the conditional, or context-dependent, nature of the world and the value of uncertainty... Langer is saying that learning by rote is disabling improvement/tweaks: >we found that when people overlearn a task so that they can perform it by rote, the individual steps that make up the skill come together into larger and larger units. As a consequence, the smaller components of the activity are essentially lost, yet it is by adjusting and varying these pieces that we can improve our performance. __On "sideways learning"__ >The standard two approaches to teaching new skills are top-down or bottom-up. The top-down method relies on discursive lecturing to instruct students. The bottom-up path relies on direct experience, repeated practice of the activity in a systematic way. >Sideways learning aims at maintaining a mindful state. As we saw, the concept of mindfulness revolves around certain psychological states that are really different versions of the same thing: >>(1) openness to novelty; >>(2) alertness to distinction; >>(3) sensitivity to different contexts; >>(4) implicit, if not explicit, awareness of multiple perspectives; and >>(5) orientation in the present. >Each leads to the others and back to itself. Learning a subject or skill with an openness to novelty and actively noticing differences, contexts, and perspectives sideways learning makes us receptive to changes in an ongoing situation such a state of mind, basic skills and information guide our behavior in the present, rather than run it like a computer program.
In the book On Intelligence (published in 2004) by Jeff Hawkins (pg. 25), he identifies [[three characteristics of intelligent systems|characteristics of intelligent systems]], that he strongly believes are missing in past and current implementations of AI in general, and Neural Networks in particular. Hawkins criticizes AI work (pg. 29), which he believe is misguided due to the focus on [["intelligent behavior"|On Intelligence]], strongly expressed in (influenced by?) the definition of the [[Turing Test|https://plato.stanford.edu/entries/turing-test/]]: >In my opinion, the most fundamental problem with most neural networks is a trait they share with AI programs. Both are fatally burdened by their focus on behavior. Whether they are calling these behaviors "answers," "patterns," or "outputs," both AI and neural networks assume intelligence lies in the behavior that a program or a neural network produces after processing a given input. The most important attribute of a computer program or a neural network is whether it gives the correct or desired output. As inspired by Alan Turing, intelligence equals behavior. > >But intelligence is not just a matter of acting or behaving intelligently. Behavior is a manifestation of intelligence, but not the central characteristic or primary definition of being intelligent. A moment's reflection proves this: You can be intelligent just lying in the dark, thinking and understanding. Ignoring what goes on in your head and focusing instead on behavior has been a large impediment to understanding intelligence and building intelligent machines. @@Hawkins' defining characteristic of intelligence is ''the ability to make predictions''@@.
!!!Definition of Exotropy This rising flow of sustainable difference is the inversion of entropy. For the sake of this narrative, call it exotropy a turning outward. Exotropy is another word for the technical term negentropy, or negative entropy. I prefer exotropy over negentropy because it is a positive term for an otherwise double negative phrase meaning "the absence of the absence of order." Exotropy, in this tale, is far more uplifting than simply the subtraction of chaos. Exotropy can be thought of as a force in its own right that flings forward an unbroken sequence of unlikely existences.
From Peter Goodliffe's book //Becoming a Better Programmer//
<html>
<table>
<tr>
<td>
<a href="resources/10000 monkeys - errors.png"><img src="resources/10000 monkeys - errors 1.png"></a>
</td>
<td>
<a href="resources/10000 monkeys - ease of use.png"><img src="resources/10000 monkeys - ease of use 1.png"></a>
</td>
<td>
<a href="resources/10000 monkeys - experience.png"><img src="resources/10000 monkeys - experience 1.png"></a>
</td>
</tr>
<tr>
<td>
<a href="resources/10000 monkeys - hell.png"><img src="resources/10000 monkeys - hell 1.png"></a>
</td>
<td>
<a href="resources/10000 monkeys - testing.png"><img src="resources/10000 monkeys - testing 1.png"></a>
</td>
<td>
<a href="resources/10000 monkeys - time.png"><img src="resources/10000 monkeys - time 1.png"></a>
</td>
</tr>
<tr>
<td>
<a href="resources/10000 monkeys - the end.png"><img src="resources/10000 monkeys - the end 1.png"></a>
</td>
</tr>
</table>
</html>
So what does technology want? Technology wants what we want the same long list of merits we crave. When a technology has found its ideal role in the world, it becomes an active agent in increasing the options, choices, and possibilities of others. Our task is to encourage the development of each new invention toward this inherent good, to align it in the same direction that all life is headed. Our choice in the [[technium|01 - My Question]] and it is a real and significant choice is to steer our creations toward those versions, those manifestations, that maximize that technology's benefits, and to keep it from thwarting itself Our role as humans, at least for the time being, is to coax technology along the paths it naturally wants to go. !!!Inevitability of trajectories Of course, long-term trends are not equivalent to inevitabilities. Some argue that these particular trends still are not "inevitable" in the future; at any moment a dark age could descend and reverse their course. That is a possible scenario. They are really only inevitable in the long term. These tendencies are not ordained to appear at a given time. Rather, these trajectories are like the pull of gravity on water. Water "wants" to leak out of the bottom of a dam. Its molecules are constantly seeking a way down and out, as if overcome with an obsessive urge. In a certain sense it is inevitable that someday the water will leak out even though it may be retained by the dam for centuries. Technology's imperative is not a tyrant ordering our lives in lockstep. Its inevitabilities are not scheduled prophesies. They are more like water behind a wall, an incredibly strong urge pent up and waiting to be released. It may seem like I am painting a picture of a supernatural force, akin to a pantheistic spirit roaming the universe. But what I am outlining is almost the opposite. Like gravity, this force is embedded in the fabric of matter and energy. It follows the path of physics and obeys the ultimate law of entropy. The force that is waiting to erupt into the technologies of the technium was first pushed by [[exotropy|04 - The Rise of Exotropy]], built up by self-organization. and gradually thrown from the inert world into life, and from life into minds, and from minds into the creations of our minds. It is an observable force found in the intersection of information, matter, and energy. and it can be repeated and measured, though it has only recently been surveyed.
Related to the [[First Noble Truth|01 - The Four Noble Truths]] about suffering is ''the story of the arrows'': The Buddha once asked a student, If a person is struck by an arrow is it painful? The student replied, It is. The Buddha then asked, If the person is struck by a second arrow, is that even more painful? The student replied again, It is. The Buddha then explained, In life, we cannot always control the first arrow. However, the second arrow is our reaction to the first. This second arrow is optional.
As [[Douglas Hofstadter]] (in his wonderful //Metamagical Themas// book [written in 1985, chapter 19, pg. 449]) says: To me, the thought that [[Lisp|Lisp]] itself might be "more conducive" to good AI [(Artificial Intelligence)] ideas than any other computer language is quite preposterous. Hofstadter claims that this viewpoint originates from what is known as the [[Sapir-Whorf|http://en.wikipedia.org/wiki/Sapir-Whorf_Hypothesis]] hypothesis, which can be explicitly stated as: ''Language controls thought''. A milder version of this hypothesis would say: Language exerts a powerful influence upon thought. Hofstadter goes on to say: In the case of computer languages, the //Sapir-Whorf thesis// would have to be interpreted as asserting that programmers in language X can think only in terms that language X furnishes them, and no others.Therefore they are strapped in to certain ways of seeing the "world", and are prevented from seeing many ideas that programmers in language L can easily see. At least this is what //Sapir-Whorf// would have you believe. I will have none of it! On the other hand, [[Alan Perlis|http://en.wikipedia.org/wiki/Alan_Perlis]] (American Computer Scientist, 1922-1990) [[said|Alan Perlis]]: A language that doesn't affect the way you think about programming, is not worth knowing. In a [[later (c. 2001) lecture, Hofstadter is softening his reaction/opinion|https://prelectur.stanford.edu/lecturers/hofstadter/analogy.html]] on the //Sapir-Whorf thesis//: >Since a sizable fraction of one’s personal repertoire of perceptual chunks is provided from without, by one’s language and culture, this means that inevitably language and culture exert powerful, even irresistible, channeling influences on how one frames events. (This position is related to the “meme’s-eye view” of the nature of thought, as put forth in numerous venues,most recently in [["The Meme Machine" by Susan Blackmore|https://www.susanblackmore.uk/the-meme-machine/synopsis/]]; see also [[Robert Wright's review of her book|https://archive.nytimes.com/www.nytimes.com/books/99/04/25/reviews/990425.25wrightt.html]]) > >Consider, for instance, such words as “backlog,” “burnout,” “micromanaging,” and “underachiever,” all of which are commonplace in today’s America. I chose these particular words because I suspect that what they designate can be found not only here and now, but as well in distant cultures and epochs, quite in contrast to such culturally and temporally bound terms as “soap opera,” “mini-series,” “couch potato,” “news anchor,” “hit-and-run driver,” and so forth, which owe their existence to recent technological developments. > >So consider the first set of words. We Americans living at the millennium’s cusp perceive backlogs of all sorts permeating our lives — but we do so because the word is there, warmly inviting us to see them. But back in, say, Johann Sebastian Bach’s day, were there backlogs — or more precisely, were backlogs perceived? For that matter, did Bach ever experience burnout? Well, most likely he did — but did he know that he did? Or did some of his Latin pupils strike him as being underachievers? Could he see this quality without being given the label? > >Or, moving further afield, do Australian aborigines resent it when their relatives micromanage their lives? Of course, I could have chosen hundreds of other terms that have arisen only recently in our century, yet that designate aspects of life that were always around to be perceived but, for one reason or another, aroused little interest, and hence were neglected or overlooked. > >My point is simple: we are prepared to see, and we see easily, things for which our language and culture hand us ready-made labels. When those labels are lacking, even though the phenomena may be all around us, we may quite easily fail to see them at all. The perceptual attractors that we each possess (some coming from without, some coming from within, some on the scale of mere words, some on a much grander scale) are the filters through which we scan and sort reality, and thereby they determine what we perceive on high and low levels. > >Although this sounds like an obvious tautology, that part of it that concerns words is in fact a nontrivial proposition, which,under the controversial banner of “Sapir-Whorf hypothesis,” has been heatedly debated, and to a large extent rejected, over the course of the twentieth century. I myself was once most disdainful of this hypothesis, but over time came to realize how deeply human thought — even my own! — is channeled by habit and thus, in the last accounting, by the repertoire of mental chunks (i.e., perceptual attractors) that are available to the thinker. I now think that it is high time for the Sapir-Whorf hypothesis to be reinstated, at least in its milder forms.
Recently (and as early as the year 2000 or thereabout :) the question of what are 21st Century Learning skills has been discussed often. I came across [[this article by Nir Eyal|http://www.nirandfar.com/2016/08/tech-distractions-addictions.html]] pointing to a challenge most of our students (an some of us too? :) face: good productivity and focus habits vs. harmful patterns, distractions and addictive behaviors. The author came up with a simple classification chart (see below) to help recognize and address possible obstacles to being productive and focused. [img[Artificial Brains|resources/product_classification.png][resources/product_classification.png]] While I recommend reading the full article, here is his "Take Away", in case you don't want to click on the [[link|http://www.nirandfar.com/2016/08/tech-distractions-addictions.html]] and be sucked into "The Internet Hole" (often a distraction :) at this point: "For thousands of years, people have struggled with distractions that keep them from living the lives they imagine. Today, people find themselves attached to their mobile phones, but history shows us it’s only the latest in a long list of hindrances. A few decades ago, people complained about the mind-melting power of television. Before that it was arcade games, the telephone, the pinball machine, comic books, the radio, even the written word. Not only is distraction here to stay, it will likely become harder to ignore as technology continues to make things even more engaging. However, that’s not necessarily a problem – it’s progress! We want products to improve, but we must also stay vigilant, asking whether “better” products bring out our better selves. To ensure that technologies and products serve us, instead of us serving them, it’s useful to take a quick inventory of the products we use most (the list is probably in your browser history or home screen on your phone), classify these products, tackle each accordingly – and then get on with building the life we want." I think that it all boils down to awareness and mindfulness; Doing "wholesome" things and avoiding harmful/destructive behaviors. May you have thoughtful, undistracted reading now and in the future.
[[Terry Pratchett]], in his excellent book [["A Hat Full of Sky"|http://discworld.wikia.com/wiki/A_Hat_Full_of_Sky]] describes an exchange between [[Tiffany Aching|http://discworld.wikia.com/wiki/Tiffany_Aching]] (the protagonist, a young witch) and the old, powerful, and majestic witch [[Esme (Granny) Weatherwax|http://discworld.wikia.com/wiki/Esmerelda_Weatherwax]]: Granny Weatherwax put down the cup and saucer [as Esme and Tiffany were having tea together]. “Child, you’ve come here to learn what’s true and what’s not, but there’s little I can teach you that you don’t already know. You just don’t know you know it, and you’ll spend the rest of your life learning what’s already in your bones. And that’s the truth.” She stared at Tiffany’s hopeful face and sighed. “Come outside then,” she said. “I’ll give you lesson one. It’s the only lesson there is. It don’t need writing down in no book with eyes on it.”^^1^^ She led the way to the well in her back garden, looked around on the ground, and picked up a stick. “Magic wand,” she said. “See?” A green flame leaped out of it, making Tiffany jump. “Now you try.” It didn’t work for Tiffany, no matter how much she shook it. “Of course not,” said Granny. “It’s a stick. Now, maybe I made a flame come out of it, or maybe I made you think one did. That don’t matter. It was me is what I’m sayin’, not the stick. Get your mind right and you can make a stick your wand and the sky your hat and a puddle your magic…your magic…er, what’re them fancy cups called?” “Er…goblet,” said Tiffany. “Right. Magic goblet. Things aren’t important. People are.” Granny Weatherwax looked sidelong at Tiffany. “And I could teach you how to run across those hills of yours with the hare, I could teach you how to fly above them with the buzzard. I could tell you the secrets of the bees. I could teach you all this and much more besides, if you’d do just one thing, right here and now. One simple thing, easy to do.” Tiffany nodded, eyes wide. “You understand, then, that all the glittery stuff is just toys, and toys can lead you astray?” “Yes!” “Then take off that shiny horse^^2^^ you wear around your neck, girl, and drop it in the well.” Obediently, half hypnotized by the voice, Tiffany reached behind her neck and undid the clasp. The pieces of the silver Horse shone as she held it over the water. She stared at it as if she was seeing it for the first time. And then… She tests people, she thought. All the time. “Well?” said the old witch. “No,” said Tiffany. “I can’t.” “Can’t or won’t?” said Granny sharply. “Can’t,” said Tiffany and stuck out her chin. “And won’t!” She drew her hand back and refastened the necklace, glaring defiantly at Granny Weatherwax. The witch smiled. “Well done,” she said quietly. “If you don’t know when to be a human being, you don’t know when to be a witch^^3^^. And if you’re too afraid of goin’ astray, you won’t go anywhere. May I see it, please?” Tiffany looked into those blue eyes. Then she undid the clasp again and handed over the necklace. Granny held it up. “Funny, ain’t it, that it seems to gallop when the light hits it,” said the witch, watching it twist this way and that. “Well-made thing. O’ course, it’s not what a horse looks like, but it’s certainly what a horse is.” ---- ^^1^^ Young Tiffany was keeping a diary which had a decorative picture of an eye (The Third Eye of witches?) on its cover. ^^2^^ Tiffany got this silver horse necklace from a boy (a Baron's son). The silver horse was shaped like the big horse carved into the White Chalk Mountains where Tiffany (and the boy) lived. From the author's notes at the end of the book: >By an amazing coincidence, the Horse carved on the Chalk [mountainside] is remarkably similar to the [[Uffington White Horse|https://en.wikipedia.org/wiki/Uffington_White_Horse]], which in this world is carved on the downlands near the village of Uffington in southwest Oxfordshire. It’s 374 feet long, several thousand years old, and carved on the hill in such a way that you can only see all of it in one go from the air. This suggests that >a) it was carved for the gods to see or >b) flying was invented a lot earlier than we thought or >c) people used to be much, much taller. ^^3^^ Maybe paraphrasing this (or a [[corollary|https://www.vocabulary.com/dictionary/corollary]]?) also yields another "teaching": > If you don't know when and how to be a learner, you don't know when and how to be a good teacher.
The evolution of ideas in Math is fascinating. [[Complex numbers|http://www.math.uri.edu/~merino/spring06/mth562/ShortHistoryComplexNumbers2006.pdf]] (and [[Imaginary Numbers|Imaginary Numbers - by Paul J. Nahin]]) are a great example of a "significant development"^^1^^ on this path. I agree with [[Israel Kleiner who wrote|http://science.cmb.ac.lk/mathematics/wp-content/uploads/sites/9/2016/06/Thinking_the_Unthinkable__the_Story_of_Compleax-numbers.pdf]]^^2^^ that as a teacher, knowing the history of your subject (in this case Math, but definitely also true for Computer Science), is very important. As [[George Polya|https://en.wikipedia.org/wiki/George_P%C3%B3lya]] had said: >How [the teacher] makes his point may be as important as the point he makes; he must personally feel it to be important. So, //imagine// if you will, (ha!), a (relatively) simple math problem: ''find two numbers which divide 10 into two parts, and the product of which is 20.'' In other words: a + b = 10 and a * b = 20. As they say, it's easy to show (and if you'd rather [[go to WolframAlpha and check|http://www.wolframalpha.com/input/?i=a%2Bb%3D10,+a*b%3D20]], go ahead :) that there are 2 "real solutions": <a href="http://www.wolframalpha.com/input/?i=a%2Bb%3D10,+a*b%3D20"><img src="resources/real equation small.png"></a> ([[click to see/calculate on Wolfram Alpha|http://www.wolframalpha.com/input/?i=a%2Bb%3D10,+a*b%3D20]]) As it turns out, the polymath [[Gerolamo Cardano|https://en.wikipedia.org/wiki/Gerolamo_Cardano]], in his [[Ars Magna|https://en.wikipedia.org/wiki/Ars_Magna_(Gerolamo_Cardano)]], explored a similar question, which for (historically understandable) reasons caused him "mental torture" (as [[the mathematician Edward Frenkel wrote|http://www.edwardfrenkel.com/einstein-summary.pdf]]). Cardano worked on the problem of how ''"To divide 10 in two parts, the product of which is 40".'' (So, just simply replacing the 20 in the problem above with 40 here :) And here is what he wrote: >It is clear that this case is impossible. Nevertheless, we shall work thus: >We divide 10 into two equal parts, making each 5. These we square, making 25. >Subtract 40, if you will, from the 25 thus produced, as I showed you in the >chapter on operations in the sixth book leaving a remainder of -15, the square root >of which added to or subtracted from 5 gives parts the product of which is 40. > >These will be 5+√−15 and 5−√−15. > >Putting aside the mental tortures involved, multiply 5+√−15 and 5−√−15 >making 25−(−15) which is +15. Hence this product is 40. And again, it's easy to show (and if you'd rather [[go to WolframAlpha and check|http://www.wolframalpha.com/input/?i=a%2Bb%3D10;+a*b%3D40]], go ahead :) that there are 2 "complex solutions": <a href="http://www.wolframalpha.com/input/?i=a%2Bb%3D10;+a*b%3D40"><img src="resources/complex equation small.png"></a> ([[click to see/calculate on Wolfram Alpha|http://www.wolframalpha.com/input/?i=a%2Bb%3D10;+a*b%3D40]]) !!!And the (possible) moral(s)/lessons of this (hi)story * This is another example of a case of willingness to "make the mental leap", despite the "mental anguish", resulting in the amazing discovery of complex numbers, with [[phenomenal implications (and applications)|https://www.ukessays.com/essays/mathematics/application-of-complex-number-in-engineering.php]]! * It is another instance of how the meaning and scope of concepts (in this case, the concept of "number") evolves * and with it, the importance of mental flexibility and openness * the important role of physical need and human curiosity in the development of new and impactful/important ideas * the role and importance of intuition and logic in the evolution of human knowledge * the nature of logical and mathematical proofs in determining "truths" * the powerful (and quite frequent) progression from "pure knowledge" to "applied knowledge" ---- ^^1^^ [[An Imaginary Tale|http://www.pucrs.br/famat/viali/tic_literatura/livros/Paul%20J.%20Nahin%20-%20An%20Imaginary%20Tale%20The%20Story%20of%20i%20the%20Square%20Root%20of%20Minus%20One.pdf]] - The Story of <a href="resources/i.png"><img src="resources/i 1.png"></a> by Paul J. Nahin ^^2^^ from [[an article by Israel Kleiner titled "Thinking the Unthinkable: The Story of Complex Numbers (with a Moral) "|http://science.cmb.ac.lk/mathematics/wp-content/uploads/sites/9/2016/06/Thinking_the_Unthinkable__the_Story_of_Compleax-numbers.pdf]] (see [[GD copy|https://drive.google.com/file/d/1BJ0vraarncN3Z3iiwZnE__-zdurUEbAJ/view?usp=sharing]]): >One can invent mathematics without knowing much of its history. One can use mathematics without knowing much, if any, of its history. But one cannot have a mature appreciation of mathematics without a substantial knowledge of its history. >[...] >To teach effectively a teacher must develop a feeling for his subject; he cannot make his students sense its vitality if he does not sense it himself. He cannot share his enthusiasm when he has no enthusiasm to share. How he makes his point may be as important as the point he makes; he must personally feel it to be important.
([[from James Iry's blog|http://james-iry.blogspot.com/2009/05/brief-incomplete-and-mostly-wrong.html]]) A [[list of computer scientists|https://en.wikipedia.org/wiki/List_of_computer_scientists]] (if you are interested in some of their accomplishments). 1801 - Joseph Marie Jacquard uses punch cards to instruct a loom to weave "hello, world" into a tapestry. Redditers of the time are not impressed due to the lack of tail call recursion, concurrency, or proper capitalization. 1842 - Ada Lovelace writes the first program. She is hampered in her efforts by the minor inconvenience that she doesn't have any actual computers to run her code. Enterprise architects will later relearn her techniques in order to program in UML. 1936 - Alan Turing invents every programming language that will ever be but is shanghaied by British Intelligence to be 007 before he can patent them. 1936 - Alonzo Church also invents every language that will ever be but does it better. His lambda calculus is ignored because it is insufficiently C-like. This criticism occurs in spite of the fact that C has not yet been invented. 1940s - Various "computers" are "programmed" using direct wiring and switches. Engineers do this in order to avoid the tabs vs spaces debate. 1957 - John Backus and IBM create FORTRAN. There's nothing funny about IBM or FORTRAN. It is a syntax error to write FORTRAN while not wearing a blue tie. 1958 - John ~McCarthy and Paul Graham invent LISP. Due to high costs caused by a post-war depletion of the strategic parentheses reserve LISP never becomes popular[1]. In spite of its lack of popularity, LISP (now "Lisp" or sometimes "Arc") remains an influential language in "key algorithmic techniques such as recursion and condescension"[2]. 1959 - After losing a bet with L. Ron Hubbard, Grace Hopper and several other sadists invent the Capitalization Of Boilerplate Oriented Language (COBOL) . Years later, in a misguided and sexist retaliation against Adm. Hopper's COBOL work, Ruby conferences frequently feature misogynistic material. 1964 - John Kemeny and Thomas Kurtz create BASIC, an unstructured programming language for non-computer scientists. 1965 - Kemeny and Kurtz go to 1964. 1970 - Guy Steele and Gerald Sussman create Scheme. Their work leads to a series of "Lambda the Ultimate" papers culminating in "Lambda the Ultimate Kitchen Utensil." This paper becomes the basis for a long running, but ultimately unsuccessful run of late night infomercials. Lambdas are relegated to relative obscurity until Java makes them popular by not having them. 1970 - Niklaus Wirth creates Pascal, a procedural language. Critics immediately denounce Pascal because it uses "x := x + y" syntax instead of the more familiar C-like "x = x + y". This criticism happens in spite of the fact that C has not yet been invented. 1972 - Dennis Ritchie invents a powerful gun that shoots both forward and backward simultaneously. Not satisfied with the number of deaths and permanent maimings from that invention he invents C and Unix. 1972 - Alain Colmerauer designs the logic language Prolog. His goal is to create a language with the intelligence of a two year old. He proves he has reached his goal by showing a Prolog session that says "No." to every query. 1973 - Robin Milner creates ML, a language based on the M&M type theory. ML begets SML which has a formally specified semantics. When asked for a formal semantics of the formal semantics Milner's head explodes. Other well known languages in the ML family include OCaml, F#, and Visual Basic. 1980 - Alan Kay creates Smalltalk and invents the term "object oriented." When asked what that means he replies, "Smalltalk programs are just objects." When asked what objects are made of he replies, "objects." When asked again he says "look, it's all objects all the way down. Until you reach turtles." 1983 - In honor of Ada Lovelace's ability to create programs that never ran, Jean Ichbiah and the US Department of Defense create the Ada programming language. In spite of the lack of evidence that any significant Ada program is ever completed historians believe Ada to be a successful public works project that keeps several thousand roving defense contractors out of gangs. 1983 - Bjarne Stroustrup bolts everything he's ever heard of onto C to create C++. The resulting language is so complex that programs must be sent to the future to be compiled by the Skynet artificial intelligence. Build times suffer. Skynet's motives for performing the service remain unclear but spokespeople from the future say "there is nothing to be concerned about, baby," in an Austrian accented monotones. There is some speculation that Skynet is nothing more than a pretentious buffer overrun. 1986 - Brad Cox and Tom Love create Objective-C, announcing "this language has all the memory safety of C combined with all the blazing speed of Smalltalk." Modern historians suspect the two were dyslexic. 1987 - Larry Wall falls asleep and hits Larry Wall's forehead on the keyboard. Upon waking Larry Wall decides that the string of characters on Larry Wall's monitor isn't random but an example program in a programming language that God wants His prophet, Larry Wall, to design. Perl is born. 1990 - A committee formed by Simon Peyton-Jones, Paul Hudak, Philip Wadler, Ashton Kutcher, and People for the Ethical Treatment of Animals creates Haskell, a pure, non-strict, functional language. Haskell gets some resistance due to the complexity of using monads to control side effects. Wadler tries to appease critics by explaining that "a monad is a monoid in the category of endofunctors, what's the problem?" 1991 - Dutch programmer Guido van Rossum travels to Argentina for a mysterious operation. He returns with a large cranial scar, invents Python, is declared Dictator for Life by legions of followers, and announces to the world that "There Is Only One Way to Do It." Poland becomes nervous. 1995 - At a neighborhood Italian restaurant Rasmus Lerdorf realizes that his plate of spaghetti is an excellent model for understanding the World Wide Web and that web applications should mimic their medium. On the back of his napkin he designs Programmable Hyperlinked Pasta (PHP). PHP documentation remains on that napkin to this day. 1995 - Yukihiro "Mad Matz" Matsumoto creates Ruby to avert some vaguely unspecified apocalypse that will leave Australia a desert run by mohawked warriors and Tina Turner. The language is later renamed Ruby on Rails by its real inventor, David Heinemeier Hansson. [The bit about Matsumoto inventing a language called Ruby never happened and better be removed in the next revision of this article - DHH]. 1995 - Brendan Eich reads up on every mistake ever made in designing a programming language, invents a few more, and creates LiveScript. Later, in an effort to cash in on the popularity of Java the language is renamed JavaScript. Later still, in an effort to cash in on the popularity of skin diseases the language is renamed ECMAScript. 1996 - James Gosling invents Java. Java is a relatively verbose, garbage collected, class based, statically typed, single dispatch, object oriented language with single implementation inheritance and multiple interface inheritance. Sun loudly heralds Java's novelty. 2001 - Anders Hejlsberg invents C#. C# is a relatively verbose, garbage collected, class based, statically typed, single dispatch, object oriented language with single implementation inheritance and multiple interface inheritance. Microsoft loudly heralds C#'s novelty. 2003 - A drunken Martin Odersky sees a Reese's Peanut Butter Cup ad featuring somebody's peanut butter getting on somebody else's chocolate and has an idea. He creates Scala, a language that unifies constructs from both object oriented and functional languages. This pisses off both groups and each promptly declares jihad. ---- ''Footnotes'' [1] Fortunately for computer science the supply of curly braces and angle brackets remains high. [2] Catch as catch can - by [[Verity Stob|https://www.theregister.co.uk/bootnotes/stob/]]
I came across [[a series of images|http://www.brainpickings.org/2013/03/28/the-art-of-cleanup-ursus-wehrli/]] by the Swiss humorist [[Ursus Wehrli|http://www.kunstaufraeumen.ch/en]] that illustrated for me what we sometimes do ("accomplish"?) in two fields which are near-and-dear to me: engineering and education. [[(more from Ursus on TED|http://www.ted.com/talks/ursus_wehrli_tidies_up_art.html]]). Some of this is echoed in [[About learning how to improvise a little better]] (or "lightening up" a bit).
In engineering there is a fine line between "the pleasure of engineering" (and "doing it right"), and "over-engineering in action" (and "engineering going overboard"). An important part of engineering is to make appropriate/justified/rational choices and trade-offs, not necessarily to maximize or minimize. It is foolish, sad and often dangerous to "extremize" in engineering.
In education there is also a danger of "overdoing it", by practicing rigid discipline and structure while teaching/learning, and not leveraging playfulness and serendipity. There is also the danger of "doing it backwards", i.e., consistently (and persistently) learning/teaching from the bottom up, starting with definitions and basic concepts, etc., and working up from there.
A domain where I feel it's painfully evident is Math.
As [[Paul Lockheart points out|resources/LockhartsLament.pdf]] in a fitting and nightmarish analogy from music, this can be "extremized" to the absurd:
>Since musicians are known to set down their ideas in the form of sheet music, these curious black dots and lines must constitute the language of music. It is imperative that students become fluent in this language if they are to attain any degree of musical competence; indeed, it would be ludicrous to expect a child to sing a song or play an instrument without having a thorough grounding in music notation and theory. Playing and listening to music, let alone composing an original piece, are considered very advanced topics and are generally put off until college, and more often graduate school.
>As for the primary and secondary schools, their mission is to train students to use this language to jiggle symbols around according to a fixed set of rules...
(the point is clear, and easily transferable to other areas of study, especially Math... :-(
[[Back to those images|http://www.zillamag.com/art/the-art-of-clean-up-by-ursus-wehrli/]]
Are we sometimes (over)doing it to learners, sucking all the fun out of it?
|[img[let there be order|./resources/Ursus-Wehrli-The-Art-of-Clean-Up-13.png][./resources/Ursus-Wehrli-The-Art-of-Clean-Up-13.png]]|[img[let there be order|./resources/Ursus-Wehrli-The-Art-of-Clean-Up-14.png][./resources/Ursus-Wehrli-The-Art-of-Clean-Up-14.png]]|
And on a larger (cosmic) scale of engineering (as a result of education?):
|[img[let there be order|./resources/Ursus-Wehrli-The-Art-of-Clean-Up-9.png][./resources/Ursus-Wehrli-The-Art-of-Clean-Up-9.png]]|[img[let there be order|./resources/Ursus-Wehrli-The-Art-of-Clean-Up-10.png][./resources/Ursus-Wehrli-The-Art-of-Clean-Up-10.png]]|
And finally, on a smaller scale (but still very important to get it right, especially if it's the writing on a bathroom door...):
|[img[let there be order|./resources/Ursus-Wehrli-The-Art-of-Clean-Up-11.png][./resources/Ursus-Wehrli-The-Art-of-Clean-Up-11.png]]|[img[let there be order|./resources/Ursus-Wehrli-The-Art-of-Clean-Up-12.png][./resources/Ursus-Wehrli-The-Art-of-Clean-Up-12.png]]|
So, back to Math education. Lockheart continues his nightmarish analogy from music:
>Of course, not many students actually go on to concentrate in music, so only a few will ever get to hear the sounds that the black dots represent. Nevertheless, it is important that every member of society be able to recognize a modulation or a fugal passage, regardless of the fact that they will never hear one. To tell you the truth, most students just aren t very good at music. They are bored in class, their skills are terrible, and their homework is barely legible. Most of them couldn't care less about how important music is in today's world; they just want to take the minimum number of music courses and be done with it. I guess there are just music people and non-music people.
...
>By concentrating on what, and leaving out why, mathematics is reduced to an empty shell. The art is not in the truth but in the explanation, the argument. It is the argument itself which gives the truth its context, and determines what is really being said and meant. Mathematics is the art of explanation. If you deny students the opportunity to engage in this activity to pose their own problems, make their own conjectures and discoveries, to be wrong, to be creatively frustrated, to have an inspiration, and to cobble together their own explanations and proofs you deny them mathematics itself. So no, I m not complaining about the presence of facts and formulas in our mathematics classes, I m complaining about the lack of mathematics in our mathematics classes.
By-the-way, Charles van Loan (a professor at Vanderbilt) voices [[similar concerns|Formalism First = Rigor Mortis. Intuition First = Rigor's Mortise]] about (initial) focus and sequencing in the Computer Science curriculum.
And in conclusion Lockheart says (about Math):
>There is such breathtaking depth and heartbreaking beauty in this ancient art form.
>How ironic that people dismiss mathematics as the antithesis of creativity.
>They are missing out on an art form older than any book, more profound than any poem, and more abstract than any abstract.
So, what is mathematics, and what do mathematicians do?
Here's [[G.H. Hardy s|http://en.wikipedia.org/wiki/G._H._Hardy]] excellent description:
>A mathematician, like a painter or poet, is a maker of patterns.
>If his patterns are more permanent than theirs, it is because they are made with //ideas//.
The following is one of many versions of this (possibly) [[urban legend|https://www.snopes.com/fact-check/the-barometer-problem/]]. The following concerns a question in a physics degree exam at the University of Copenhagen: "Describe how to determine the height of a building with a barometer." One student replied: "You tie a long piece of string to the neck of the barometer, then lower the barometer from the roof of the tower to the ground. The length of the string plus the length of the barometer will equal the height of the building." This "highly original" answer so incensed the examiner that the student was failed immediately. The student appealed on the grounds that his answer was indisputably correct, and the university appointed an independent arbiter to decide the case. The arbiter judged that the answer was indeed correct, but did not display any noticeable knowledge of physics. To resolve the problem it was decided to call the student in and allow him six minutes in which to provide a verbal answer which showed at least a minimal familiarity with the basic principles of physics. For five minutes the student sat in silence, forehead creased in thought. The arbiter reminded him that time was running out, to which the student replied that he had several extremely relevant answers, but couldn't make up his mind which to use. On being advised to hurry up the student replied as follows: "Firstly, you could take the barometer up to the roof of the tower, drop it over the edge, and measure the time it takes to reach the ground. The height of the building can then be worked out from the formula H = 0.5g x t^^2^^. But bad luck on the barometer." "Or if the sun is shining you could measure the height of the barometer, then set it on end and measure the length of its shadow. Then you measure the length of the tower's shadow, and thereafter it is a simple matter of proportional arithmetic to work out the height of the tower." "But if you wanted to be highly scientific about it, you could tie a short piece of string to the barometer and swing it like a pendulum, first at ground level and then on the roof of the tower. The height is worked out by the difference in the gravitational restoring force T = 2 pi square root (l/g)." "Or if the tower has an outside emergency staircase, it would be easier to walk up it and mark off the height of the tower in barometer lengths, then add them up." "If you merely wanted to be boring and orthodox about it, of course, you could use the barometer to measure the air pressure on the roof of the tower and on the ground, and convert the difference in millibars into feet to give the height of the building." "But since we are constantly being exhorted to exercise independence of mind and apply scientific methods, undoubtedly the best way would be to knock on the janitor's door and say to him 'If you would like a nice new barometer, I will give you this one if you tell me the height of this tower'." The student was Niels Bohr.
This letter/email is inspired by [[Advice from an experienced programmer]] and was sent to students who have taken one Exploratory CS course: The semester is almost over, and you have finished your second Computer Science course at Pinewood. I hope you'll decide to keep engaging with Computing in the future beyond this introductory foundation. In the future, I hope you'll do some coding either as part of your professional career, or as a hobby. The important part is not that you program, but what you do with programming, as it can be a source of joy, beauty, innovation, and usefulness. As I had told you throughout the course, programming as a career can be a good and interesting one, but there are many other good and interesting careers. Actually, you may enjoy another career more, and be more successful in it, if you use programming as part of that other career or profession. Professionals who can code in biology, medicine, government, law, sociology, physics, art, history, and mathematics, to name just a few disciplines, are more respected and can do amazing things to advance those areas and their lives. Computer Science is a relatively young domain. The importance of knowing how to code will only grow with time; you can enjoy the advantage of an "early adopter". So, go ahead, explore this fascinating intellectual and creative pursuit; enjoy and improve your life and the lives of others using and creating with code. I hope you have a strong finish of the semester, and I wish you an enjoyable (and well-deserved :) break! """ """ (see also [[More words of encouragement on the road (code? :) ahead]]). (see also [[Attitude Matters Too (in programming as in life)]]).
Computational Thinking (CT) and Computational Literacy^^''1''^^ have been getting significant attention and focus (and some funding) in the last few years, with various organizations and initiatives supporting it. The thinking about CT is evolving, and there is no single agreed-upon definition of it^^''2''^^, but following is my (working) definition^^''3''^^, inspired by the thoughtful viewpoints expressed in a [[report by the National Academies|http://www.nap.edu/catalog.php?record_id=12840]]: >Computational Thinking is the study and development of human capabilities and processes for solving problems, designing systems, and understanding human behavior, in order to magnify and enhance those human aspects. It has roots in mathematics, engineering, technology, and science, and draws on concepts and methodologies fundamental to the sciences in general and computer science and technology in particular. ^^''3''^^ A partial list of key contributors and participants in evolving CT is: * The National Science Foundation (NSF) ([[example presentation by Jeannette M. Wing |http://www.nsf.gov/attachments/114603/public/2009_02_19_cstb-ct.ppt]], 2.8MB .ppt) * [[The National Academies|http://www8.nationalacademies.org/cp/projectview.aspx?key=48969]] * [[International Society for Technology in Education (ISTE)|http://www.iste.org/learn/computational-thinking]] * [[Computer Science Teachers Association (CSTA)|http://csta.acm.org/Curriculum/sub/CompThinking.html]] * [[Google's Exploring Computational Thinking|http://www.google.com/edu/computational-thinking/index.html]] * Universities/academia like [[Carnegie Mellon (CMU)|http://www.cs.cmu.edu/~CompThink/]], [[Northwestern|http://osep.northwestern.edu/projects/ct-stem]], [[DePaul|http://compthink.cs.depaul.edu/]], [[University of Washington|http://csprinciples.cs.washington.edu/sixpractices.html]], and others. The CT model described in the [[ISTE Leadership Toolkit|http://www.iste.org/docs/ct-documents/ct-leadership-toolkit-8-22-11FC0F82895322.pdf?sfvrsn=2]] identifies some key skills mapped to CT abilities across school grades. This is useful, and definitely a good step in outlining a "CT vocabulary and Progression Chart". It mainly focuses on the skills/capabilities as essential building blocks, but doesn't propose a coherent framework nor curricula. The CT model described in the [[CSTA matrix|http://csta.acm.org/Curriculum/sub/CurrFiles/CTExamplesTable.pdf]] is aligned with the ISTE model and vocabulary, and adds a dimension of different domains/subjects/curricula (e.g. Math, Science, Language Arts]]. This effort is also focusing mainly on the building blocks for CT, and not on an overarching framework. The [[Google Exploring Computational Thinking repository|http://www.google.com/edu/computational-thinking/lessons.html]] has a collection of specific lesson ideas leveraging technologies across domains/subjects/curricula. The examples are narrowly focused on applying computation, programming, automation to very specific problems. Following is my work-in-progress framework for Computational Thinking and Computational Literacy, which is focusing on //Problem Solving// as the "guiding lens", so as to show how various building blocks (including key ones from the models above) may fit together in a set of processes, and ways of thinking and behaving (hence, //framework//) guided by Computational Thinking principles and capabilities. I've chosen problem solving since this is one of the main goals 21st Century Education initiatives are aiming to improve. !!!Click the image to see a zoomable PDF version of my (work-in-progress) problem-solving-focused, computational-thinking-guided framework <a href="resources/Computational Thinking process HM.pdf" target="new"><img src="resources/Computational Thinking process HM.png" width="90%" height="90%" /></a> [ext[The drill-down interactive framework|resources/Computational Thinking process HM live.pdf]] (expandable/collapsible PDF) !!A few notes on the framework in the larger context of Computational Thinking and Computational Literacy * The framework aims mainly at STEM (Science, Technology, Engineering, Math) education, but is not limited to these domains/curricula. On the other hand, it's not just about Computer Science and programming. As a matter of fact, Computational Thinking and practices can be learned and exercised without computers (but it may be less fun ;-). To paraphrase the famous, hard-boiled Dutch computer scientist Edsger Dijkstra: >Computational Thinking is no more about computers than astronomy is about telescopes. * To balance the point above, CT is not the end-all-be-all in terms of an educational framework, model, and scope. So far, it does not specifically address, for example, domains like social behavior (teamwork, empathy, persuasive argumentation, etc.), morality (fairness, prejudice, justice, etc.), and others, which are important "21^^st^^ Century Skills" and abilities (and educational frameworks). As CT matures, I expect it to integrate and compliment other frameworks and domains, and this is already starting to happen, where it's being linked with social and moral contexts and behaviors (see [ext[Six Computational Thinking Practices|resources/CT_sixpractices.pdf]] from Washington University, practice 1 - effects, and practice 6 - teamwork) * There has been [[some legitimate concern|http://csta.acm.org/Curriculum/sub/CurrFiles/JonesCTOnePager.pdf]] regarding the definition and scope (too abstract, too narrow) of CT, which should be kept in mind as the thinking and practice around CT evolves and matures. * A [[set of questions|http://cs.gmu.edu/cne/pjd/GP/gp_faq.html]] regarding the appropriate principles to create and apply to CT and Computer Science (a somewhat narrow and computer science centric focus can be seen in the early publications of [[Wing|http://www.cs.cmu.edu/afs/cs/usr/wing/www/publications/Wing06.pdf]]) is brought up by the computer scientist [ext[Peter Denning|http://cs.gmu.edu/cne/pjd/GP/GP-site/about_us.html]] and others. Denning also warned in [ext[a viewpoint article|resources/Denning-Beyond Computational Thinking.pdf]] in the [[Communications of the ACM|http://cacm.acm.org/]], of the danger of equating CT with programming, and brought up thoughtful points to consider on the way "Beyond Computational Thinking" (which is the title of his article). * To counter this, some computer scientists make an effort to broaden the scope and extent of CT (for example: [ext[Seven Big Ideas of Computer Science|resources/CT_sevenbigideas.pdf]] (and don't let the title fool you -- it's not only about Computer Science!) * Identifying CT skills and capabilities that "go together" as part of an activity (e.g. Hypothesizing, or Defining Questions) helps promote processes and behaviors that can be developed into CT //Best Practices// and effective ways of thinking. * The framework recognizes that skills and capabilities are building blocks in different contexts within the problem solving process, and therefore can repeat multiple times. Also, the pattern of input-processing-output is a nested and repeatable one, and can/should be applied at multiple levels within bigger contexts. * The framework also emphasizes that CT __does not__ consist of just applying technology or computation to a single activity, task, or phase of problem solving. CT "lives" not only in the skills/capabilities building blocks, but (and as importantly) also in the process, links, and flow from one task and activity to the next. ---- ^^''1''^^ - An interesting view on [[Computational Literacy|Computing Literacy]] and comparison to mastering calculus as a new literacy in Math, by Andrea diSessa ^^''2''^^ - from the [[Report of a Workshop on The Scope and Nature of Computational Thinking (2010)|http://www.nap.edu/openbook.php?record_id=12840&page=65]]: >Discussions held at the February 2009 workshop did not reveal general agreement among workshop participants about the precise content of computational thinking, let alone its structure. Nevertheless, the lack of explicit disagreement about its elements could be taken as reflecting a shared intuition among workshop participants that computational thinking, as a mode of thought, has its own distinctive character. >Building on this shared intuition, it is fair to say that most workshop participants agreed that more deliberation is necessary to achieve greater clarity about what is encompassed under the rubric of computational thinking and how these elements are structured relative to each other. ^^''3''^^ - This is my definition, inspired by the contributions captured in the National Academies report by: Peter Lee, Bill Wulf, Peter Denning, Gerald Sussman, Jeannette Wing, Edward Fox, Uri Wilensky, Robert Constable.
The "[[CS Sage|https://en.wikipedia.org/wiki/List_of_computer_scientists]]" Alan Kay was making when he quipped:
>A good point of view is worth many IQ points.
So here's an example:
<html>
<table>
<tr>
<td>
<img src="resources/pv1.jpg">
</td>
</tr>
<tr>
<td>
<img src="resources/pv2.jpg">
</td>
</tr>
<tr>
<td>
<img src="resources/pv4.jpg">
</td>
</tr>
</table>
</html>
The [[Palo Alto Airport|https://www.google.com/maps/place/Palo+Alto+Airport/@37.4550078,-122.1107903,15z/data=!4m5!3m4!1s0x0:0x45fa9fd3819cf9e2!8m2!3d37.4550078!4d-122.1107903]], as viewed from the [[Byxbee Baylands Park|https://www.google.com/search?q=byxbee+park&client=firefox-b-1-ab&tbm=isch&tbo=u&source=univ&sa=X&ved=2ahUKEwjw59S48unfAhVRcq0KHfydD6MQsAR6BAgEEAE&biw=1559&bih=910]].
I have to admit that the title of the book [["Programming as if People Mattered — Friendly Programs, Software Engineering, and Other Noble Delusions"|http://wiki.c2.com/?ProgrammingAsIfPeopleMattered]] about User Centered Design by [[Nathaniel Borenstein|https://en.wikipedia.org/wiki/Nathaniel_Borenstein]] intrigued me :) His self-deprecating (actually profession-deprecating, which is a somewhat (entirely? :) different thing) quote struck (an ominous, but in a black-humor kind of way) chord too: >The most likely way for the world to be destroyed, most experts agree, is by accident. That's where we come in. We're computer professionals. We cause accidents. But lest you think Borenstein is a total cynic and/or total jester, here is his observation and advice on the healthy/wise attitude a programmer should take in relation to their code/projects/products, which I totally agree with: >A good attitude to take, from the first day of any programming project, is that the system being built is fundamentally flawed and doomed. The goal of such a project, then, is simply to build a system that will last long enough for a better one to come along, and perhaps also to be, for a brief moment suspended between eternities, the best program of its kind yet built. > >When viewed from this perspective, the inevitable demise and abandonment of the software is a good thing, because it means that it has done its job and something better has come along. Often, one can arrange things so that the replacing software is also one's own; there is a peculiar satisfaction in driving the nail into one's own coffin, and it is surely less painful for a programmer to see his software abandoned if he played an active role in creating the system that replaces it.
Here are a few recommendations/observations from a thoughtful, sound, and common-sensical blog post titled [["A Helpful Guide to Reading Better"|https://fs.blog/reading/]]: * Ideally, the way you read is tailored to whether you’re reading for entertainment, information, or understanding. [[The Levels of Reading|https://fs.blog/how-to-read-a-book/]] will help you read more effectively and efficiently. * [[Choose what you read wisely|https://fs.blog/2013/08/choose-your-next-book/]] * be quick to start books, [[quicker to stop them|https://fs.blog/2017/09/shouldnt-slog-books/]], and read the best ones again right after you finish. * [[don’t read what everyone else is reading|https://fs.blog/2013/04/reading-what-everyone-else-is-reading/]]. Rather than read new books, [[focus on old ones|https://fs.blog/2012/06/c-s-lewis-on-reading-old-books/]]. * [[Take notes while reading|https://fs.blog/2013/11/taking-notes-while-reading/]] ** At the end of each chapter write a few bullet points that summarize what you’ve read and make it personal if you can — that is, apply it to something in your life. Also, note any unanswered questions. When you’re done with the book, put it down for a week. ** Pick up the book again and go through all your notes. Most of these will be garbage but there will be lots you want to remember. Write the good stuff on the inside cover of the book along with a page number. ** Copy out the excerpts by hand or take a picture of them to pop into Evernote. Tag accordingly. * Good reading habits not only help you read more but help you read better. Here’s the [[Farnam Street system for remembering what you read|https://fs.blog/2017/10/how-to-remember-what-you-read/]]. ** Before you start reading a new book, take out a blank sheet of paper. Write down what you know about the subject you’re about to read — a mind map if you will. ** After you are done with a reading session spend a few minutes adding to the map (I use a different color ink). ** Before you start your next reading session, review the mindmap (I use mine as a bookmark sometimes.) ** Put these mind maps into a binder that you periodically review. * [[Find more time to read|https://fs.blog/2013/09/finding-time-to-read/]] ** get in [[the habit of reading|https://fs.blog/2015/12/twenty-five-pages-a-day/]]
I've recently read the book //The varieties of scientific experience - a personal view of the search for God// by Carl Sagan. The book is a collection of lectures edited by Sagan's life companion Ann Druyan, based on the famous Gifford Lectures on Natural Theology Sagan gave in 1985 at the University of Glasgow. As Druyan says about the Gifford Lectures in the introduction to the book: >[Sagan] would be following in the footsteps of some of the greatest scientists and philosophers of the last hundred years including James Frazer, Arthur Eddington, Werner Heisenberg, Niels Bohr, Alfred North Whitehead, Albert Schweitzer, and Hannah Arendt. >Carl saw these lectures as a chance to set down in detail his understanding of the relationship between religion and science and something of his own search to understand the nature of the sacred. In the chapter on Extraterrestrial Intelligence Sagan tells a story revealing a lot about human nature: As is bound to happen roughly every 17 years or so, Earth and Mars get close together as they both revolve around the Sun. The year was 1877, and that year, an Italian astronomer, Giovani Schiaparelli, looked at Mars through one of the newly built large telescopes in Italy and saw many intricate, fine, straight lines on the surface of that planet. He called them //canali// meaning "channels" or "grooves" in Italian. This was promptly translated into English as "canals", with implications of design, intelligence, and large planetary engineering construction work. This sentiment was later picked up by a rich American astronomer, Parcival Lowell, who was convinced that Schiaparelli was right about the "Martian canals", and "that the planet was covered by a network of intersecting single and double straight lines, that these lines passed over enormous distances and therefore could correspond only to engineering works on the most massive imaginable scale". Lowell decided to build a large telescope in Arizona (which he naturally called the Lowell Observatory ;-) to further investigate the phenomenon. As Sagan describes the developments: >Other observers also found the canals; that is, drew them. Photographing them was much more difficult. The argument was that atmospheric "seeing" was unreliable, due to the intrinsic turbulence and unsteadiness of the Earth's atmosphere, which generally prevent you from seeing the canals. But every now and then, by chance. the atmosphere steadies, the turbulent eddies of air are not in your line of sight to Mars, and just for a moment you can see the planet as it truly is with this network of straight lines. Lowell reasoned that experienced observers could more reliably draw the lines they saw through the telescope, since time exposure photography would be very difficult with the recurring turbulences and atmospheric distortions. There were other astronomers who, for the life of them couldn't see the straight lines, but there was a range of explanations: They were not in the best sites for their telescopes. They were not experienced observers. They were not adequate draftsmen. They were biased against the idea of canals on Mars. Lowell and Schiaparelli were by no means the only astronomers who could find the canals. Astronomers all over the world saw them, drew them, mapped them. Drawings were compared, similarities were found. And there were literally hundreds of individual canals that were named. >Lowell deduced from these straight lines an ancient civilization on Mars more advanced than we, having to face a planetary drought of proportions unprecedented on Earth. And their solution was to construct a vast, globe-girdling network of canals to carry liquid water from the melting polar caps to the thirsty inhabitants of the equatorial cities. What's more, it was possible to conclude, Lowell thought, something of the politics of the Martians, because the network crossed the entire planet. Therefore there was a world government on Mars, at least as far as engineering detail went. And Lowell went so far as to be able to identify the capital of Mars, a particular spot on the surface called Solis Lacus, the Lake of the Sun, from which six or eight different canals seemed to emanate. As you probably know, this story got into the popular consciousness, into folk literature (like H.G. Wells's //War of the Worlds//), Sci-Fi novels (like Edgar Rice Burroughs's (of Tarzan fame)), and radio and the movies (like Orson Welles's broadcast about The Martian Invasion, which scared Americans in 1938). Sagan continues: >And yet there are no canals on Mars. Not one. The whole thing is wrong. It's a mistake. It is a failure of the human hand-eye-brain combination. Lowell's idea evoked a passion, I think a very understandable and humane passion. The vision of more advanced beings on a neighboring planet, with a world government, struggling to keep themselves alive, was a wonderful idea. It was so wonderful that the wish to believe it trumped the scrupulousness of the investigative process. and he sums it up: >So what can we conclude from this? Well, we can conclude that in a sense Lowell was right, that the canals of Mars are a sign of intelligent life. The only question is which side of the telescope the intelligent life is on. So, as the title says: - "Keen (as in 'sharp' or 'penetrating' but also 'having or showing eagerness or enthusiasm') observers" - yes! - "Seeing what you think" - absolutely possible!
A language that doesn't affect the way you think about programming, is not worth knowing.
It is said that the second cheapest university department to fund is the math department. Its members only need pencils, paper, and wastebaskets. The cheapest department to fund is the philosophy department. They don't need wastebaskets.
(From Out Here: Poems and Images from Steens Mountain Country) """ As thought to mind, so to the string plucked, or touched, or bowed, the music is, a wrinkling of the air as immaterial and brief as sunlight glancing on a wave. The silence in these empty lands is long. Voice is as mortal as the word it says, with little time to speak the thought, to tell or sing the quick idea of those who live. So brief the spoken word, the airy thing in which are placed our deepest constancies, though by its love or life may stand or fall, and in it is the power to ruin or save. The silence in these empty lands is long. Rock has no tongue to speak or voice to sing, mute, heavy matter. Yet as I lift up this dull desert stone, the weight of it is full of slower, longer thoughts than mind can have. Be my mind, stone lying on my grave. The silence in these empty lands is long. The stars have long to listen. Be my song. """
In an [[article covering an interesting and seemingly effective "constructionist experiment"|http://stager.org/articles/eurologo2005.pdf]] in a troubled juvenile detention facility (The Maine Youth Center), Gary Stager (the principal investigator) summarized a few key principles from Seymour Papert (who participated in the experiment), which nicely compliment what he had said about [[exploring a new way to teach math|An Exploration in the Space of Mathematics Educations]]. The eight ''big ideas'' he lists are: * __learning by doing__. We all learn better when learning is part of doing something we find really interesting. We learn best of all when we use what we learn to make something we really want. * __technology as building material__. If you can use technology to make things you can make a lot more interesting things. And you can learn a lot more by making them. This is especially true of digital technology: computers of all sorts including the computer-controlled Lego in our Lab. * __hard fun__. We learn best and we work best if we enjoy what we are doing. But fun and enjoying doesn’t mean “easy.” The best fun is hard fun. Our sports heroes work very hard at getting better at their sports. The most successful carpenter enjoys doing carpentry. The successful businessman enjoys working hard at making deals. * __learning to learn__. Many students get the idea that “the only way to learn is by being taught.” This is what makes them fail in school and in life. Nobody can teach you everything you need to know. You have to take charge of your own learning. * __taking time__ – the proper time for the job. Many students at school get used to being told every five minutes or every hour: do this, then do that, now do the next thing. If someone isn’t telling them what to do they get bored. Life is not like that. To do anything important you have to learn to manage time for yourself. This is the hardest lesson for many of our students. * __you can’t get it right without getting it wrong__. Nothing important works the first time. The only way to get it right is to look carefully at what happened when it went wrong. To succeed you need the freedom to goof on the way. * __do unto ourselves what we do unto our students__. We are learning all the time. We have a lot of experience of other similar projects but each one is different. We do not have a preconceived idea of exactly how this will work out. We enjoy what we are doing but we expect it to be hard. We expect to take the time we need to get this right. Every difficulty we run into is an opportunity to learn. The best lesson we can give our students is to let them see us struggle to learn. * __we are entering a digital world where knowing about digital technology is as important as reading and writing__. So learning about computers is essential for our students’ futures BUT the most important purpose is using them NOW to learn about everything else.
I recently came across (and bought for a quarter, since I didn't have the required nickel to pay for it :) an IBM Technical Report (from 1973!), written by 4 researchers ^^1^^ connected to Ken Iverson, the inventor of APL (A Programming Language) and [[the winner of the Turing Award|http://amturing.acm.org/award_winners/iverson_9147499.cfm]] (1979). Their 70 page paper/report (and 14 page appendix) is packed of insights into how to use APL to create insight and deeper learning. The exciting thing (for me :) was that this slim publication holds so many insights about using Any Programming Language (not just APL) for teaching and learning, that I feel it could (and should) impact entire curricula, from the sciences, through math, art, and, of course, Computer Science. It addresses one of the strong beliefs I have about making cross-domain/discipline connections, whenever and wherever possible, using Computing as an excellent facilitator and "bridge". The authors start by saying: This report is based upon three central ideas: * that key concepts in various disciplines may be represented by functions; * that a language such as APL, permits a readable, formal definition of a function and a means of executing it and thereby accumulating the experience necessary to understand it; and * that it is possible (but, unfortunately, not usual) to Write Computer programs so that they correspond directly to the functional concepts of a discipline. They seem to fully support my belief in the benefits of using Computing to gain insights in other subjects and knowledge domains: >Efforts to use the computer in education have in the past been focused primarily on measuring educational achievement by using its data-processing powers, on its ability to present and manage programmed instruction, or on the machine itself (as the subject of study). A new role for the computer emerges when the discipline of programming is used to represent explicitly a topic's structure, and thus to provide a basis for insight. And their definition of gaining insight in a knowledge domain: >To say that a student has gained insight into a topic means that he has come to see an underlying structure, and that, by referring to that structure, he is able to state and apply rules which explain or predict. In particular, he is able to abstract the rules from their context, and generalize them to new situations. One requirement of an educational process is that it provide the student language in which to describe his disciplines and in which to think about them. They highlight the critical role of functions in mastering a knowledge domain, and define data and functions as essential parts in a model, expressing ideas that later surfaced in the movement to Object Oriented Programming and the paradigm shift it created: > The fundamental ideas of a discipline depend upon two aspects of the way we choose to represent it: > 1. Data: those attributes that we choose to note and measure thereby become the facts by which knowledge of an event is encoded, and in terms of which we think about it. > 2. Functions: the transformations from one representation of data to another, or the relations between different sets of data. ''On Modeling'' (in/of a discipline/domain) - The authors rightly claim that "the choice of functions by which data are treated influence the selection of facts worth observing." This is true both pedagogically (which I think is the focus of their report) and philosophically (i.e., epistemologically). The refer to domain modeling by saying that "Taken together, a collection of functions imposes a structure on the understanding of a topic." and add: > For some time, [[Falkoff|https://en.wikipedia.org/wiki/Adin_Falkoff]] and [[Iverson|https://en.wikipedia.org/wiki/Kenneth_E._Iverson]] have argued that a system of programs constitutes a framework for a discipline (see DSLs below). The purpose and usefulness of modeling with functions and data is something scientists and teachers strive for all the time, because: > If a topic is well understood and its description well organized, a function useful in the description of one phenomenon can usually be used again in others. The creation of a unified and consistent system of definitions is, of course, what scientists are continually attempting. In similar fashion, teachers or authors can select the functions by which they develop a topic so that these form a coherent system. ''On Domain Specific Languages'' ([[DSLs|https://en.wikipedia.org/wiki/Domain-specific_language]]) - they talk (decades before [[Martin Fowler|http://martinfowler.com/books/dsl.html]] and others) about: > In each field or discipline, the user may in effect extend the language to embrace the functions appropriate to it. The user may "pyramid" definitions, using those from each level as terms in the definition of those at the next. and > The content of various disciplines can be expressed in such a way that APL expressions can be used in books, on paper, and at the blackboard to achieve briefer, clearer, more general and more effective summary than is possible with conventional algebra or the various ad hoc extensions that each discipline tends to develop. They make an aside on poets and scientists, which I think is insightful :) >Poets or artists sometimes decry the precision that the scientists espouse ; they claim to prefer instead the many-layered ambiguity that literature permits. They miss the point that the generality that in art is achieved by ambiguity is equally an aim of science. Scientists, like poets, seek to state a function so generally that it applies to things which once seemed unrelated, and thereby gain some insight into all of them. At the heart of the paper/report is the desire to use APL (or Any PL) as a tool for gaining insight and improve learning and mastering a discipline/knowledge Domain: >Our aim is not to use programming as an end in itself, but rather to integrate the use of algorithms into the study and exposition of any discipline using formal or mathematical models. Underlying this conception of a common language for man and machine is a conception of the relation between machine and student. In general, we have assumed that if a function is defined, it is because the student is expected both to use it and to understand it. That means that he should expect to be able to display its definition and understand what he reads there. Each function should therefore be not a black box but a glass box, whose inner mechanism is visible to any who need or care to study it. ''On Scafolding'' and gradual/layered revealing of a domain's structure (functions): > On occasion we wish temporarily to withhold from a student what the definition of a function is, so that he may practice his analytic powers by testing its performance. We have considered such exercises with locked functions a sort of paradigm of the sciences : We observe the world, and collect data on the results that nature's unknown functions provide. The scientist's faith is that the world can indeed be reduced to comparatively simple functions, and that experiment will lead him to propose definitions for functions whose performance will duplicate what he observes. But even in the case in which knowledge of a function's definition is for the time being withheld, the student has the right and the power ultimately to see and to understand what he sees. They emphasize the "open use" of the computer and exploration of domains/disciplines with it (the computer, not just APL, mind you!): > We call this way of using the machine open use of the computer. A great deal can be done with no pre-programmed definitions at all, i.e. with a "bare" APL machine. Generally speaking, it is the student (or the teacher) who initiates activities, not the machine. The task of the student is to develop his definitions of functions and to acquire experience in exploring their consequences. The computer * thus to him a laboratory device, an arena for testing his ideas by evaluating the results his functions produce. !!!!Some implications of the "open use/exploration" approach to teaching: This style of use has far-reaching consequences for the style in which teaching is conducted. Some of these have already been mentioned, and others will be described in more detail in a moment. Here we list some of them: 1. The work with the computer can be integrated into the presentation of the subject matter itself a. with minimum attention t○ programming, machine, language, or computer science (unless those are desired in their own right); b. with no requirement that students spend much time individually at the terminal (although if the facility is available it is usually advantageous to do so); c. with no dependence on a computer program for the particular course, other than access to an APL system and guidance from text or teacher on the functions that may be developed. 2. The functional approach, using APL to define the functions, has important benefits quite apart from the use of computers. a. There are significant advantages of the notation even if no use of terminals is made. b. The role of the terminal in many cases is to provide rapid and decisive testing of proposals developed by students; it thereby serves as a powerful motivating device, but not one that is indispensable to the content of instruction. c. Even where the terminal is used for carrying out practical computations, the language may still be used apart from the terminal for developing the underlying concepts and procedures. 3. In the classroom, a terminal has many uses as a laboratory device, so that a group can witness the outcome of expressions collectively or individually proposed. a. Group use, with occasional individual use outside class hours, permits a relatively large number of students per terminal. b. Terminal manufacturers have not thus far provided for collective viewing of the output of a terminal, and there are few devices well adapted for display to a group. However, adequate results are obtained by mounting a small TV camera on a conventional terminal, and connecting it to one or more TV monitors in the classroom. 4. APL notation and a functional approach are applicable to a wide variety of courses in mathematics and the sciences. a. The overhead of getting started with the notation and with terminals can be spread over many disciplines. b. Although direct use of the notation and of terminals can be started with students of junior high school age or even younger, it remains relevant throughout their subsequent secondary and university education. c. If one anticipated that students would make wide use of APL upon reaching secondary school, many of their elementary courses from kindergarten onward could lay a foundation for the general conception of function and for elements of APL notation, thus making the subsequent introduction of computing even easier. ---- ^^1^^ - Paul Berry, J. Bartoli, C. Dell'Aquila, V. Spadavecchia
[img[Piet Hein on wisdom|./resources/Knuth - wisdom 1.png]] In a short [[video clip|https://youtu.be/v678Em6qyzk?t=20]], Donald Knuth (a "[[CS Sage|https://en.wikipedia.org/wiki/List_of_computer_scientists]]") shows the following [[grook (form of poetry)|http://www.archimedes-lab.org/grooks.html]] by [[Piet Hein|http://www.piethein.com/page/piet-hein-16/]] hanging on the wall in his home, which I think typifies his "slow, deep thinking" approach to everything he has done.
Maria Popova in a [[BrainPickings|https://www.brainpickings.org/]] blogpost [[covers an interesting book|https://www.brainpickings.org/2012/05/04/a-technique-for-producing-ideas-young/]] by James Webb Young, written in 1939: //A Technique for Producing Ideas//. Young sees new ideas as nothing but producing new __//combinations//__ of old elements. But the key is to be able to see new __//relationships//__ between these elements. He makes an __//observation//__ which I think is very significant to learning and education: >Here, I suspect, is where minds differ to the greatest degree when it comes to the production of ideas. To some minds each fact is a separate bit of knowledge. To others it is a link in a chain of knowledge. It has relationships and similarities. It is not so much a fact as it is an illustration of a general law applying to a whole series of facts. Young breaks up the process of producing new ideas into 5 ''steps'': 1. GATHERING RAW MATERIAL - you need to create and maintain a pool of "raw material" (the "elements" to be combined). It is hard work, it's ongoing, and it's part of being a lifelong learner (and inventor, or innovator, or "original thinker"). 2. DIGESTING THE MATERIAL - Young has a vivid image for this step/process: >take the different bits of material which you have gathered and feel them all over, as it were, with the tentacles of the mind. You take one fact, turn it this way and that, look at it in different lights, and feel for the meaning of it. You bring two facts together and see how they fit. What you are seeking now is the relationship, a synthesis where everything will come together in a neat combination, like a jig-saw puzzle. 3. UNCONSCIOUS PROCESSING - unfortunately, a "black box" but //essential// step, where you "turn the problem over to your unconscious mind and let it work while" you do other, unrelated things (like sleep, listen to music, go to the theater or movies, read poetry or a detective story, or whatever else "stimulates your imagination and emotions"). 4. THE A-HA MOMENT - where things click together, as if out of nowhere (similar to how [[Alan Kay describes it|AHA! Moments]]). 5. IDEA MEETS REALITY - where you "show your idea around" and discuss it with caring but judicious people. This is very useful since: >You will find that a good idea has, as it were, self-expanding qualities. It stimulates those who see it to add to it. Thus possibilities in it which you have overlooked will come to light.
A wonderful (clear-eyed, but with some tongue-in-cheek) poem by Wislawa Szymborska. I liked it that Szymborska "poured humanness into a math vessel". (David Eagleman has [[a different take/statistics on life|Sum by David Eagleman]]). Since I don't know Polish, I took the creative freedom of putting together a "mix-and-match version" of two translations (based on my [[preferences|Possibilities - by Wislawa Szymborska]]): one from [[Joanna Trzeciak|http://chavelaque.blogspot.com/2005/08/word-on-statistics-by-wislawa.html]] and the other from [[Clare Cavanagh and Stanislaw Baranczak|http://www.poetry-chaikhana.com/blog/2011/04/04/wislawa-szymborska-a-contribution-to-statistics/]]. """ Out of a hundred people those who always know better — fifty-two doubting every step — nearly all the rest, glad to lend a hand if it doesn’t take too long — as high as forty-nine, always good because they can’t be otherwise — four, well maybe five, able to admire without envy — eighteen, suffering illusions induced by youth (which passes) — sixty, give or take a few, not to be taken lightly — forty and four, living in constant fear of someone or something — seventy-seven, capable of happiness — twenty-something, tops, harmless alone, but savage in crowds — half at least, cruel when forced by circumstances — better not to know, not even approximately, wise after the fact — just a couple more than wise before it, getting only things out of life — thirty (I wish I were wrong), hunched in pain, without a flashlight in the dark — eighty-three sooner or later, righteous — quite a few, thirty-five, righteous and understanding — three, worthy of compassion — ninety-nine, mortal — a hundred out of a hundred. a figure that has not changed yet. """ I think that since the end result is 100% guaranteed (i.e., it will eventually happen even without any effort/action/intention on one's part), it may make one think about which category(ies) one wants to (make an effort to) belong to, and live by^^1^^ (and in this way, change the statistics :) ---- ^^1^^ - As they say in Pirkei Avot (The Chapters of the Elders) 3:15 : Everything is foreseen, and freewill is given. (הַכֹּל צָפוּי, וְהָרְשׁוּת נְתוּנָה.)
I like reading the various inter-connected topics covered on [[Brain Pickings|http://www.brainpickings.org/index.php]], Their belief and common theme about creativity an innovation (from the site) is: >...creativity, after all, is a combinatorial force. It's our ability to tap into the mental pool of resources ... and to combine them in extraordinary new ways. In order for us to truly create and contribute to the world, we have to be able to connect countless dots, to cross-pollinate ideas from a wealth of disciplines, to combine and recombine these ideas and build new ideas like LEGOs. I came across a somewhat different, but related (connected ;-) perspective expressed by [[Robert Logan|http://www.physics.utoronto.ca/people/homepages/logan/]] in his book [[What is Information?|What is Information? by Robert Logan]], where in [ext[chapter 5|resources/logan_information_ch5.pdf]] he's mentioning George Basalla, the author of the book [ext[The Evolution of Technology|resources/Basalla - the evolution of technology - sample.pdf]] (1988): >Basalla [says] that technology evolves through a process of descent and modification: "Any new thing that appears in the made world is based on some object already in existence." He cites many examples of how innovative technologies borrowed significantly from earlier technologies citing the cotton gin, the electric motor and the transistor as three examples. Gutenberg's moveable type printing press is another example. Then he mentions Thomas Kuhn: >The mechanism for the propagation of science's organization is what Thomas Kuhn (1972) termed normal science. Every success in science gives rise to a paradigm, which is articulated and applied to as many phenomena as possible. This is the mechanism of descent. Once a paradigm fails to provide a satisfactory description of nature a period of revolutionary science begins with the search for a new paradigm. This is the mechanism of modification. If the new paradigm provides a satisfactory explanation to the science community by providing replicable results a new round of normal science begins. This is the mechanism of selection. Science propagates its organization through normal science and evolves by descent, modification and selection just like living organisms. The analogy between the Darwinian evolution of living organisms and the process of descent, modification and selection in Kuhn's model led him to cautiously conclude at the end of his analysis of scientific revolutions the following: >>The analogy that relates the evolution of organisms to the evolution of scientific ideas can easily be pushed too far. But with respect to the issues of this closing section it is very nearly perfect. . . . Successive stages in that developmental process are marked by an increase in articulation and specialization. And the entire process may have occurred, as we now suppose biological evolution did, without benefit of a set goal, a permanent fixed scientific truth, of which each stage in the development of scientific knowledge is a better exemplar (Kuhn 1972, pp. 172-73). And Karl Popper: >Karl Popper (1979, p. 261) whose description of science differs from that of Kuhn s, nevertheless also found an analogy between the evolution of science and that of living organisms: >>The growth of our knowledge is the result of a process closely resembling what Darwin called 'natural selection'; that is, the natural selection of hypotheses: our knowledge consists, at every moment, of those hypotheses which have shown their (comparative) fitness by surviving so far in their struggle for existence; a competitive struggle which eliminates those hypotheses which are unfit.
In an article in Aeon titled [["We could all do with learning how to improvise a little better"|https://aeon.co/ideas/we-could-all-do-with-learning-how-to-improvise-a-little-better]] by Stephen T. Asma (a professor of philosophy at Columbia College Chicago), he writes about [["loosening up a bit"|A case for "loosening up a bit"]] (or "lightening up" a bit) and brings up a few good points: * According to Han Fei Zi (a Chinese philosopher, c280-233 BCE) moving decision-making away from people and putting it in stable institutions is a successful strategy for large, complex and expansionary societies, which are increasingly made up of strangers. On the other hand, bureaucracy is soul-crushing and alienating in its inflexibility and inhumanity. What is more, it exacts a psychological price. * But, life is intrinsically changing, moving, disappointing and positively surprising. Meeting life with unbending expectations is a recipe for disaster. * According to Laozi (a Chinese philosopher, Laozi, 5th century BCE), it is by being receptive to immediate experience (wu-wei) that the wise person adapts perfectly to the unique needs of the situation. * But improvisation isn’t foolproof either. * Sometimes, the problem with "bad/failed" improvisation is a kind of domain overreach. The great physicist, for example, is not automatically qualified to make good poetry. The great business-person is not inevitably effective in the domain of government. And yet, sometimes, overreach is exactly what is needed. In other words: there are no rigid rules/guidelines (ha!). * We may think that good improvisation is discernible only in hindsight; we know it’s good because it worked. However, this cannot be entirely correct. Often, we do know good improvisation when we see it in action (in, for example, a musical performance, sports, business/political negotiations, personal/adaptive teaching). * the single greatest predictor of quality improv is simply experience. But there’s nothing simple about experience. A great improviser usually had thousands of hours of practice and problem-solving underneath every improvisation. * This kind of experience makes good improv highly intuitive in a biological sense, not a mystical sense. It taps into the subtle systems of animal awareness, mostly unconscious, that we all possess, such as body-awareness (proprioception), personal space (proxemics), and arousal states such as fight or flight. Muscle memory is loaded with this kind of intuitive wisdom. * the improviser usually does not have optimal resources (they work in a resource-deficient environment/context). And this paucity of resources is the very condition of creativity because it forces a kind of lateral thinking. * Improvisation is rule-governed in some cases, but moderately so. It is a flexible practice that sees rules as elastic. Improv is serviceable rather than optimal. Improvisational manoeuvres already exist within a system of received conventions, and only experience can help you decide to respect or ignore them. * Failing is a major aspect of improvisation. Failure is the thing we learn from, so it’s the cornerstone of productive experience. * Aristotle described improvisational decision-making as ‘practical reason’, distinct from rule-following logic. [[Barry Schwartz discusses this "Practical Wisdom"|Barry Schwartz on Aristotle on Practical Wisdom]] well. * we’ve all known enough young talent to doubt his generalisation about age [that (only?) age and experience enable exceptional performance], but his wider point about experience is correct. And Asma summarizes: >Ultimately, improvising is a form of receptivity to experience, and also a behavioural style based upon that experience. It evolved as part of our cognitive operating system to make good use of available resources. It is a fundamental inheritance, emerging out of our primate evolution. But the narcissistic improviser and the inexperienced improviser – so popular these days in politics and celebrity culture – leaps tragically into delicate situations with no plans, practice, tact or ability to read the room. That is an improvising ape of an altogether different kind.
My name is Haggai Mark. I live in Northern California. I am a Learning Solutions designer and implementer, and CS^^1^^ and STEM^^2^^ course developer and teacher, with strong engineering expertise in system/platform/software architecture and implementation, as well as deep experience in technology-enabled instructional design and development. I have a [[Masters degree from Stanford University in Learning, Design, and Technology|http://ldtprojects.stanford.edu/~hmark/index_stanford.html]]. I am blessed with an awesome family: a wonderful wife and 3 great children. <a href="./resources/fin-StateMachine-ite.gif" target="new"><img src="./resources/fin-StateMachine-ite.gif" width="50%" height="50%" /></a> @@font-size:16pt;''*''@@ "I am a strange loop"^^3^^ [[(and even Doug said so himself)|On the strange human loop]] @@font-size:16pt;''**''@@ infinite ~StateMachine (in-finite ~StateMachine ***) :) @@font-size:16pt;''***''@@ [[A simple (but interesting) Cellular Automaton (State Machine): Wolfram's Rule 110|Cellular Automaton Rule 110]] ---- ^^1^^ CS = Computer Science ^^2^^ STEM = Science, Technology, Engineering, Mathematics ^^3^^ on [["strange loopiness"|http://en.wikipedia.org/wiki/I_Am_a_Strange_Loop]] (as in self-reference) a-la and //about// Douglas Hofstadter, in [[indexing|On indexers and indexing]] [img[adr|./resources/adr.png][./resources/adr.png]]
In another Q&A session at the Gifford Lectures^^1^^, Carl Sagan brings up a crucial point (and often missed "logical trick"): Questioner: I'd like to ask you about why you think any omnipotent being would want to leave evidence for us. CS: I think I entirely agree with what you say. There is no reason I should expect an omnipotent being to leave evidence of His existence, except that the Gifford Lectures^^1^^ are supposed to be about that evidence. And I hope it is clear that the fact that I do not see evidence of such a God's existence does not mean that I then derive from that fact that I know that God does not exist. That's quite a different remark. Absence of evidence is not evidence of absence. Neither is it evidence of presence. And this is again a situation where our tolerance for ambiguity^^2^^ is required. See also [[BrainPickings' Varieties of Scientific Experience: Carl Sagan on Science and God|https://www.brainpickings.org/2013/12/20/carl-sagan-varieties-of-scientific-experience/]] ---- ^^1^^ Gifford Lectures on Natural Theology - Sagan spoke at the university of Glasgow in 1985, following in the footsteps of such celebrated philosophers as James Frazer, Arthur Eddington, Werner Heisenberg, Niels Bohr, Alfred North Whitehead, Albert Schweitzer, and Hannah Arendt. ^^2^^ see [[Richard Hemming on ambiguity|The importance of tolerating ambiguity and uncertainty]].
!!This week I went to a talk by the Venerable Ajahn Jayasaro (Shaun Michael Chiverton) at Stanford. He finished his interesting talk titled "Moving smoothly along a bumpy road" with the following story. A monk somewhere in Southeast Asia, decided to embark on a trip on foot to a remote mountain, to mediate on its top. A few days into the trip he got lost. As he was walking through a small village, he saw an old woman sitting at the side of the road cleaning and sorting lentils. The monk approached her and asked: Grandmother, grandmother, how long is it to the mountain? The old woman did not respond. So he asked again: Grandmother, grandmother, please tell me, how long do I have to walk to get to the mountain? And again, the old woman kept sorting the lentils and did not answer. Being a Buddhist monk, he asked for the third time: Grandmother, please tell me, how long to the mountain? And still, the woman would not respond. So, the monk turned back to the road and started walking again. After taking a few steps, he heard the old woman behind him saying: three days. He turned around and asked her: if you knew the answer, why didn't you tell me, even though I asked three times? And the woman responded: I couldn't. First, I had to know how determined you are, and how fast you walk. !!This reminded me of a different story about being lost and asking for directions, this time in the West. Two young professionals in the Seattle, WA area decided to go on a hot-air balloon trip. They rented a balloon for the day, but being inexperienced, they got lost, and didn't know how to return back to the landing spot. As they were floating in the sky, they passed above a group of tall office buildings, something that looked like an industrial office campus, and spotted a man standing on the terrace on the top of one of the buildings. So they lowered the balloon, and shouted to the man on the terrace: We are lost. Can you please tell us where we are? To which the man on the terrace answered: you are in a hot-air balloon above building 10 of this campus. One man in the balloon scratched his head, puzzled at this answer, while the other man started confidently navigating and after a short while landed them at the landing spot. The puzzled man asked the navigator: how did you know where to go, even though the man on the top of the building gave us totally useless information? To which the navigator responded: Since the answer was totally accurate but seemingly useless, I knew he must be an engineer. And from the campus buildings I figured it had to be the Microsoft Engineering Campus (in Seattle/Redmond, WA), so finding the landing spot was easy. You can say many things about these two stories, but one thing you could say relevant to "actionable learning" is: accurate information is important, but not sufficient. You must have the right context.
After teaching [[a course at Citizen Schools|The "Acing Racing" course]] using [[Sage|http://www.sagemath.org/]], and covering basic math/physics concepts like distance, speed, time, graphs, etc., at the 6-8 grade level, I implemented a different program/simulation using [[Scratch|http://scratch.mit.edu/]]. My intention was to make it more concrete for the kids (Sage is "drier" since it has been originally written by mathematicians, for mathematicians; whereas Scratch has been written by education-aware/focused people at MIT, and is therefore "kid-friendly"). I also thought of using Scratch for teaching both the math/physics concepts and some basic programming concepts (algorithmic solutions, task breakdown, routines/functions/sub-routines, looping, etc.) [ext[The result|resources/Scratch_car_racing.png]] is a relatively simple race scenario, [[published on the web|http://scratch.mit.edu/projects/myh9090/1871961]], enabling kids to explore and experience the various factors that go into "traditional" middle school distance-speed-time problems, so they can get a concrete and personal sense of the math involved.
This has some good insights into and implications for Instructional Design, but, and to [[paraphrase Blaise Pascal|I have made this longer than usual because I have not had time to make it shorter.]], since I don't have time to "originally write", I will just "massively cite" :) In a [[research paper|https://chilab.asu.edu/sites/all/themes/chilab/public/publication_files/JEE-Menekse-7-1-2013.pdf]], Michelene Chi defines and tests the effectiveness of 3 different models of active learning: Active, Constructive, and Interactive. This research supports Chi’s ICAP (Interactive, Constructive, Active, Passive) hypothesis, whose classification of overt learning activities can help researchers, instructional designers, and instructors determine activities appropriate for their intended research or instruction. The results suggest that when implemented properly, interactive modes are most effective, constructive modes are better than active and passive modes, and active modes are better than passive ones for student learning. * Being Active >In the active mode, students undertake overt activities that activate their own knowledge within the boundaries of the desired content. Students do something or manipulate the instructional information overtly, rather than passively receive information or instruction while learning or studying (Chi, 2009). Active activities emphasize the selected passages or manipulated components of a task, thus allowing students to pay more attention to them. The cognitive processes hypothesized by Chi that correspond with active activities are activating and searching for related knowledge, and encoding, storing, or assimilating new information with activated knowledge. These processes strengthen the existing knowledge and fill the gaps in knowledge, making it more retrievable and more complete. * Being Constructive >In the constructive mode, students undertake activities in which they generate knowledge that extends beyond the presented materials. In the active mode, for example, simply repeating a paragraph or underlining text does not extend beyond what was presented. But self- explaining, or explaining aloud to oneself a concept presented in a text, is constructive because it constructs meaning beyond the given content. The following types of activities can all be considered to be constructive: drawing a concept map, taking notes in one’s own words from a lecture, generating self-explanations, comparing and contrasting different situations, asking comprehension questions, solving a problem that requires constructing knowledge, justifying claims with evidence, designing a study, posing a research question, generating examples from daily lives, using analogy to describe certain cases, monitoring one’s comprehension, making strategic decisions in a video game, converting text-based information into symbolic notation, drawing and interpreting graphs, or hypothesizing and testing an idea. * Being Interactive >The interactive mode refers to two or more learners undertaking activities that develop knowledge and understanding extending beyond the materials being studied (similar to the constructive mode), but the interaction of the learners further enables them to build upon one another’s understanding. The main (but surface-level) difference between the interactive and constructive mode is that learners in the latter engage in activities alone. However, interaction between learners affords them the benefit of receiving feedback or prompting from each other, with each partner having some complementary knowledge or perspectives. The different knowledge and perspectives further provide the opportunity for co-creation or joint-construction, which is not possible in solo activities. Chi claims (and [[backs it up with experimental data|https://chilab.asu.edu/sites/all/themes/chilab/public/publication_files/JEE-Menekse-7-1-2013.pdf]]) that: >Through this give-and-take discussion [in the interactive mode of learning], students would be building knowledge in a way that would not have occurred if they had been work- ing alone, since they can build on each other’s contributions or refine and modify an original idea in ways that can produce novel ideas. Thus, interactive learning has the potential to be more beneficial than constructive learning, in which single individuals can only extend beyond the given information with their own ideas; in interactive learning, two individuals can further enrich the topic of discussion through jointly extending on a given content topic from two different perspectives and sets of ideas.
In an interesting [[collection of responses to letters from readers who want to write poetry|https://www.poetryfoundation.org/articles/68657/how-to-and-how-not-to-write-poetry-56d2484397277]], my favorite poet, [[Wislawa Szymborska|Wislawa Szymborska's Nobel Prize lecture (1996)]], gives some excellent advice^^1^^, which (not surprisingly?) beautifully applies to writing computer programs. To paraphrase Szymborska^^1^^: Some programmers (or students learning to program) may say, ‘I know my code has many faults, but so what, I’m not going to stop and fix it.’ And why is that? Perhaps because they hold coding so sacred? Or maybe they consider it insignificant? Both ways of treating programming are mistaken, and what’s worse, they free the novice coder from the necessity of working on his code. It’s pleasant and rewarding to tell our acquaintances that 'we just slapped things together' on Friday at 2:45 a.m. and/or that 'inspiration struck, and we just hacked it'. But the truth is that 'beautiful, elegant code' takes assiduously correcting, crossing out, and revising those otherworldly 'inspirations'. Spirits are fine and dandy, but even coding has its prosaic side.” So it's absolutely true about both poetry and programming. One has moments of excitement and joy during the creative parts of the process. But, there are (probably more) parts which are "mundane"^^2^^, and require discipline, perseverance, ingenuity, positive and playful attitude, cool and patience. Or as Alan Perlis (a "[[CS Sage|https://en.wikipedia.org/wiki/List_of_computer_scientists]]") quipped: > It goes against the grain of modern education to teach students to program. What fun is there to making plans, acquiring discipline, organizing thoughts, devoting attention to detail, and learning to be self critical. ---- ^^1^^ - the original advice from Wislawa Szymborska (translated by Clare Cavanagh) > To Heliodor from Przemysl: “You write, ‘I know my poems have many faults, but so what, I’m not going to stop and fix them.’ And why is that, oh Heliodor? Perhaps because you hold poetry so sacred? Or maybe you consider it insignificant? Both ways of treating poetry are mistaken, and what’s worse, they free the novice poet from the necessity of working on his verses. It’s pleasant and rewarding to tell our acquaintances that the bardic spirit seized us on Friday at 2:45 p.m. and began whispering mysterious secrets in our ear with such ardor that we scarcely had time to take them down. But at home, behind closed doors, they assiduously corrected, crossed out, and revised those otherworldly utterances. Spirits are fine and dandy, but even poetry has its prosaic side.” ^^2^^ which require a certain state of mind, or as Szymborska advises: "Let’s take the wings off and try writing on foot, shall we?"
This is inspired by [[Advice from an Old Programmer|http://learnpythonthehardway.org/book/advice.html]] by Zed Shaw, the author of //[ext[Learn Python the Hard Way|http://learnpythonthehardway.org/book/]]//. This actually inspired me to [[write/email to my students|A few words of encouragement (and advice :)]] who have already taken one exploratory/intro CS class. You have finished this course, and I hope you'll decide to continue programming. Programming may be part of your professional life, or it may be a hobby. Here are a few things I'd like to say as someone who has programmed from an early age, has been enjoying good and productive careers programming and teaching, and still enjoys it in various forms to this day. Over the years, I've been picking up quite a few programming languages. I would learn a new language either because I had to (as a requirement for a project), or because I "fell in love" with some aspect or capability of it (e.g., lambda calculus, objects, functional paradigm). On this journey I found that [[Alan Perlis]] was right when he said: >A language that doesn't affect the way you think about programming (and problem solving - my addition), is not worth knowing. At the end, it's not the languages that matter but what you do with them. Don't get sucked into the occasional "religious wars" surrounding programming languages. Sometimes, with the excitement and new vistas of a new language (or fad), it's easy to forget this point, but this ''is'' the point of programming. What you //do// with a programming language is the important part, and is the source of joy, beauty, engagement and usefulness. A unique aspect of programming is that it is a creative and intellectual activity which can produce interactive art. You can create art(ifacts) which interact and communicate with its users. Unlike other art forms it is dynamic (interactive) ''and'' it flows both ways (to and from the user/participant). Programming as a career can be a good and interesting one, but there are other good and interesting careers. Actually, you may enjoy your career more, and be more successful if you use programming as part of //another// career or profession. Professionals who can code in biology, medicine, government, sociology, physics, history, and mathematics, to name a few, are respected and can do amazing things to advance those disciplines. Computer Science and programming are relatively young disciplines. They are truly in their early stages of development, and have barely reached their full potential in terms of impact on our lives. Their importance will only grow with time; you can enjoy the advantage of an "early adopter". So, go ahead, explore this fascinating intellectual and creative pursuit; enjoy and improve your life using it. The activity of programming will change you. It will not make you better or worse, just different. You will develop new capabilities, new ways to be creative, to analyze, to figure things out, to be playful. Some people may be intimidated by your abilities and skills; some may not like it, or be jealous. Don't fall into the trap labeling people who know how to program as nerds, socially challenged, or somehow strange. You now know how to code, and this is pretty cool and empowering!
In an interesting book review (of //The Internet of Us - Knowing More and Understanding Less in the Age of Big Data//^^1^^ by Michael P. Lynch) in The New Yorker titled [[After The Fact|http://www.newyorker.com/magazine/2016/03/21/the-internet-of-us-and-the-end-of-facts]] Jill Lepore, who is a professor of American History at Harvard, makes some interesting historic observations. (see also [[The importance of telling the whole truth]]) She reminds us of the frightening sentence about truth manipulation: >Everything faded into mist. The past was erased, the erasure was forgotten, the lie became truth. (George Orwell, 1984, Part 1, Chapter 7) and writes: >The past has not been erased, its erasure has not been forgotten, the lie has not become truth. But the past of proof is strange and, on its uncertain future, much in public life turns. In the end, it comes down to this: the history of truth is cockamamie, and lately it’s been getting cockamamier. She mentions Michael P. Lynch's "thought experiment" about "knowledge implants" (per Google’s Larry Page who has promised, “where if you think about a fact it will just tell you the answer”) in our body, and then: >picture this: overnight, an environmental disaster destroys so much of the planet’s electronic-communications grid that everyone’s implant crashes. It would be, Lynch says, as if the whole world had suddenly gone blind. There would be no immediate basis on which to establish the truth of a fact. No one would really know anything anymore, because no one would know how to know. I Google, therefore I am not. Lepore points out from history: >A long historical precedent stands behind these judicial methods for the establishment of truth, for knowing how to know what’s true and what’s not. In the West, for centuries, trial by combat and trial by ordeal—trial by fire, say, or trial by water—served both as means of criminal investigation and as forms of judicial proof. >[...] Trial by combat and trial by ordeal place judgment in the hands of God. Trial by jury places judgment in the hands of men. It requires a different sort of evidence: facts. >A “fact” is, etymologically, an act or a deed. It came to mean something established as true only after the Church effectively abolished trial by ordeal in 1215, the year that King John pledged, in Magna Carta, “No free man is to be arrested, or imprisoned . . . save by the lawful judgment of his peers or by the law of the land.” In England, the abolition of trial by ordeal led to the adoption of trial by jury for criminal cases. This required a new doctrine of evidence and a new method of inquiry, and led to what the historian Barbara Shapiro has called “the culture of fact”: the idea that an observed or witnessed act or thing—the substance, the matter, of fact—is the basis of truth and the only kind of evidence that’s admissible not only in court but also in other realms where truth is arbitrated. Between the thirteenth century and the nineteenth, the fact spread from law outward to science, history, and journalism. __As an aside__ - another (less bloody, but nonetheless possibly still hurtful) way to establish truth, or at least view things from a different perspective in order to "push back" on them, is wit/ridicule/humor/irony/satire. This is mentioned in the article [[Bend Sinister|https://monoskop.org/images/1/14/Goriunova_Olga_ed_Fun_and_Software_Exploring_Pleasure_Paradox_and_Pain_in_Computing.pdf]] by artist and programmer [[Simon Yuill|http://www.lipparosa.org/]], who quotes [[Lord Shaftesbury (Anthony Ashley Cooper, 3rd Earl of Shaftesbury)|https://plato.stanford.edu/entries/shaftesbury/]]: >In 'Sensus Communis - an Essay on the Freedom of Wit and Humour' (1709), Shaftesbury argues that irony and satire (what he calls ‘raillery’) are an ideal means of testing the logic and substance of debate: >>They may perhaps be Monsters, and not Divinitys, or Sacred Truths, which are kept thus choicely, in some dark Corner of our Minds: The Specters may impose on us, whilst we refuse to turn ’em every way, and view their Shapes and Complexions in every light. For that which can be shewn only in a certain Light, is questionable. Truth, ’tis suppos’d, may bear all Lights: and one of those principal Lights or natural Mediums, by which Things are to be view’d, in order to a thorow Recognition, is Ridicule it-self, or that Manner of Proof by which we discern whatever is liable to just Raillery in any Subject. >In subjecting ideas to the test of ridicule, humour acts as an ‘instrument of reason’ exposing that which claims to be proportionate and true yet which rests upon a logic that is deformed and ugly. Lepore continues: >But the movement of judgment from God to man wreaked epistemological havoc. It made a lot of people nervous, and it turned out that not everyone thought of it as an improvement. For the length of the eighteenth century and much of the nineteenth, truth seemed more knowable, but after that it got murkier. Somewhere in the middle of the twentieth century, fundamentalism and postmodernism, the religious right and the academic left, met up: either the only truth is the truth of the divine or there is no truth; for both, empiricism is an error. That epistemological havoc has never ended: much of contemporary discourse and pretty much all of American politics is a dispute over evidence. Lynch, in his book, claims that we are now at another turning point in the history of knowing and facts. Lepore writes: >Then came the Internet. The era of the fact is coming to an end: the place once held by “facts” is being taken over by “data.” This is making for more epistemological mayhem, not least because the collection and weighing of facts require investigation, discernment, and judgment, while the collection and analysis of data are outsourced to machines. “Most knowing now is Google-knowing—knowledge acquired online,” Lynch writes in “The Internet of Us” (his title is a riff on the ballyhooed and bewildering “Internet of Things”). We now only rarely discover facts, Lynch observes; instead, we download them. Of course, we also upload them: with each click and keystroke, we hack off tiny bits of ourselves and glom them on to a data Leviathan. >“The Internet didn’t create this problem, but it is exaggerating it,” Lynch writes, and it’s an important and understated point. Blaming the Internet is shooting fish in a barrel—a barrel that is floating in the sea of history. It’s not that you don’t hit a fish; it’s that the issue is the ocean. No matter the bigness of the data, the vastness of the Web, the freeness of speech, nothing could be less well settled in the twenty-first century than whether people know what they know from faith or from facts, or whether anything, in the end, can really be said to be fully proved. And like relying on GPS and voice directions for navigation: >When we Google-know, Lynch argues, we no longer take responsibility for our own beliefs, and we lack the capacity to see how bits of facts fit into a larger whole^^1^^. Essentially, we forfeit our reason and, in a republic, our citizenship. You can see how this works every time you try to get to the bottom of a story by reading the news on your smartphone. She concludes by alluding, I think, to civil, non-religious morality and human government by writing: >People who care about civil society have two choices: find some epistemic principles other than empiricism on which everyone can agree or else find some method other than reason with which to defend empiricism. Lynch suspects that doing the first of these things is not possible, but that the second might be. He thinks the best defense of reason is a common practical and ethical commitment. I believe he means popular sovereignty. That, anyway, is what Alexander Hamilton meant in the Federalist Papers, when he explained that the United States is an act of empirical inquiry: “It seems to have been reserved to the people of this country, by their conduct and example, to decide the important question, whether societies of men are really capable or not of establishing good government from reflection and choice, or whether they are forever destined to depend for their political constitutions on accident and force.” The evidence is not yet in. ---- ^^1^^ - [[Alan Kay]] expressed similar concerns (in a [[video (43 min.)|https://www.youtube.com/watch?v=gTAghAJcO1o]]) about the current state of technology (and state of mind of technologists) when he said "It should be [[Big Meaning|http://planspace.org/20141125-alan_kay_on_big_data/]], not Big Data" (i.e., that's what we should aim for).
[[Alan Kay|https://en.wikipedia.org/wiki/Alan_Kay]] (a "[[CS Sage|https://en.wikipedia.org/wiki/List_of_computer_scientists]]"), at OOPSLA 1997, gave an [[insightful talk|https://www.youtube.com/watch?v=oKg1hTOQXoY]] titled "The computer revolution hasn't happened yet" ([[transcript|http://www.vpri.org/pdf/m2007007a_revolution.pdf]]), and in it he mentions (and recommends) Arthur Koestler's book //The Act of Creation// and pictorially shows [[Bisociation|http://www.bisociations.com/aboutus/Biso.html]] (a term coined by Koestler) as an interception of 2 "geometrical planes": the pink one which we live in most of the time, and where innovation is mainly optimization of things, and the (perpendicular to the pink) blue plane, where innovation takes you to new dimensions (literally from 2D pink, to 3D on the blue plane). Kay also makes a nice comparison between our reactions at the moment of this disruptive innovation^^1^^, or a paradigm shift^^2^^, and illustrates the reaction in Humor, Science, and Art: >Most creativity is a transition from one context into another where things are more surprising. There’s an element of surprise, and especially in science, there is often laughter that goes along with the “Aha.” Art also has this element. Our job is to remind us that there are more contexts than the one that we’re in — the one that we think is reality. <a href="resources/Alan_Kay_AHA_moments.png"><img src="resources/Alan_Kay_AHA_moments_small.png"></a> ---- ^^1^^ - See also [[It's about Big Meaning, not Big Data.]] ^^2^^ - See [[Zen Physics, meaning and understanding]]
Artificial Intelligence
<<list-links "[tag{!!title}]">>
<<list-links "[tag{!!title}]">>
In an [[inspiring and thought provoking talk called "Rethinking Computer Science Education"|https://www.youtube.com/watch?v=N9c7_8Gp7gI]], CS Pioneer and Big Ideas Thinker [[Alan Kay|https://en.wikipedia.org/wiki/Alan_Kay]] (a "[[CS Sage|https://en.wikipedia.org/wiki/List_of_computer_scientists]]") shared his thoughts on CS Education.
Main Points of the talk:
1. The context humans should care about: Don't worry only about preparing children for the job market
- worry about how to grow a successful next generation since this is the goal of the current generation
- worry about how to evolve good citizenship
- worry about how to create a "rich environment" ("man does not live by bread alone")
2. Humanity 101
- our mind is "very theatrical" - we respond theatrically/emotionally to our environment
- our minds are tiny (bad at multi-tasking, 7+/- 2 items, etc.)
- we are mostly non-human (we are mainly reptilian and mammalian)
3. We need to establish "real computer science"
- Alan Perlis - meant that we need a "science of processes" - a science to study processes and things in process
- processes in mechanics, biology, society, politics, chemistry, tech/engineering, mental etc.
- the Big Idea: Computing should do a "math" for all processes
4. CAD - Simulate - Fabricate
- we need to do more design in CS, so we can do sim and fab
- Programming languages are really user interfaces; they are all Turing Equivalent so no need to get hung up on them
- some of them run faster than others
- some of them allow you to write less code than others
- some allow you to think and express new ideas - and that's the important part
5. Thresholds - tracking and being driven by "wiggly curves" and ups and downs is meaningless
- we should think about a threshold of "what is really needed" and going above that is what should guide us
- if we are below the threshold, we know we need to close the quality gap
- Better is an enemy of what is actually needed. It drives and makes us happy if we get incremental progress, even if it is under the threshold
- Perfect is also dangerous - because it discourages you from getting anywhere above the threshold, since it will always be "less than perfect"
Just teaching people to code doesn't teach them to think.
Steve Jobs sequence: "everyone should learn how to code. It teaches you how to think. Badly.
|borderless|k
|[img[Jobs 1|./resources/Jobs1.png][./resources/Jobs1 copy.png]]|[img[Jobs 2|./resources/Jobs2.png][./resources/Jobs2 copy.png]]|[img[Jobs 3|./resources/Jobs3.png][./resources/Jobs3 copy.png]]|[img[Jobs 4|./resources/Jobs4.png][./resources/Jobs4 copy.png]]|
|borderless|k
- Francis Bacon warned against errors in thought and judgement coming from 4 sources (he called "idols"):
- errors due to our genetics (see Humanity 101 above),
- errors due to our culture (beliefs, fads, etc.),
- errors due to our language (not representing thing as they are),
- errors due to academia (coming up with bad ideas and perpetually teaching them)
- Bacon called for a set of heuristics to deal with the world, a new way of dealing with knowledge.
- Science is not the knowledge.
- Science (and [[elsewhere, Thinking|Thinking is the negotiation of relationships between our noisy representations and "what's out there".]]) is the negotiation of relationships between our noisy representations and "what's out there".
- to think of science as the way to know the truth is wrong, and we should not teach it as such.
- Science is the most powerful thought system ever invented, because it gave up the idea of knowing the truth, and substituted it with a sequence of false ideas, some of which are incredibly powerful.
- computers and computing are representers, and are an excellent way to represent and simulate ideas and examine complexities.
In an [[inspiring and thought provoking talk called "The Power of Simplicity"|https://www.youtube.com/watch?v=NdSD07U5uBs]], CS Pioneer and Big Ideas Thinker [[Alan Kay|https://en.wikipedia.org/wiki/Alan_Kay]] (a "[[CS Sage|https://en.wikipedia.org/wiki/List_of_computer_scientists]]") shared his thoughts on Simplicity.
* (t =~9:00) __One way to achieve simplicity (of a solution)__ is not by finding the simplest building blocks to solve a problem, but finding slightly more sophisticated building blocks to create your solution from (Kay's example is Kepler trying to explain/fit the orbits of planets with ellipses instead of circles)
* (t = ~10:00) "There is no concept of progress in our genes" - Our genes have code for coping with situations ("resiliency"). So when we work for a company or are part of an organization, we often (and soon enough) find that the company/organization is not working in an optimal way (to put it mildly). So we can either quit or cope, since the company/org is not likely to change.
** the company/org will not easily change, because this is not its "mission". It is working on its "A Task" (what the company/org thinks its all about) and changing/evolving is not its "A Task".
** Most companies/orgs don't have a "B Process" which would look at the "A Task" and see if it is really/still most efficient.
** and rarely has a co/org a "C Process" which would look at whether the "A Task" is even still relevant and question the basic/fundamental assumptions and reasons.
* So, __another way to achieve and maintain (!) simplicity (of a company or organization and its output/product/deliverable)__ is to prioritize the "B Process" and the "C Process" (see above), and not just focus on "A Task".
* (t = ~13:00) Part of finding a good solution is finding out what the (bigger) context is. In other words, finding out what the real/big problem to solve is, not just the current/immediate problem at hand. But most of us are taught and get rewarded for solving problems, not for finding bigger ones (on the way to solving //them//). When someone comes up with a bigger problem they usually get shot down ("why are you coming up with a bigger problem? We have enough problems already!"). So, __another way to achieve simplicity (of a solution)__ is to identify, analyze, and solve the bigger context and not get stuck in the rut of the small, in-context problems.
* (t = ~41:00) Incremental thinking is the killer of all great ideas. Think of an idea (or a glimmer of an idea) without worrying about how you are going to get from here to there.
<<list-links "[tag{!!title}]">>
In his great book //[[Cryptonomicon|https://en.wikipedia.org/wiki/Cryptonomicon]]// Neal Stephenson describes a meeting between [[Alan Turing|https://en.wikipedia.org/wiki/Alan_Turing]] and Lawrence Waterhouse (a fictitious character in the book; an American mathematician and cryptographer who supposedly worked with Turing when they both were at Princeton before WWII). Turing and Waterhouse meet in a pub not too far from Bletchley Park^^1^^, and upon entering the pub and seeing Turing reading a tome at a pub table, Waterhouse asks: >"Designing another machine, Dr. Turing?" >[... Alan] frowns and looks at him quizzically. "How on earth did you guess I was designing another machine? Simply a guess based on prior observations?" >"Your choice of reading material," Waterhouse says, and points to Alan's book: the //RCA Radio Tube Manual// ^^2^^. >Alan gets a wild look. "This has been my constant companion," he says. "You must learn about these valves, Lawrence! Or tubes as you would call them. Your education is incomplete otherwise. I cannot believe the number of years I wasted on //sprockets//! God!" >"Your zeta-function machine^^3^^? I thought it was beautiful," Lawrence says. >"So are many things that belong in a //museum//," Alan says. >"That was six years ago. You had to work with the available technology," Lawrence says. >"Oh, Lawrence! I'm surprised at you! If it would take ten years to make the machine with //available// technology, and only //five// years to make it with a new technology, and it will take only //two// years to //invent// the new technology, then you can do it in //seven// years by inventing the new technology first!" >"Touche." >"This is the new technology," Alan says, holding up the //RCA Radio Tube Manual// like Moses brandishing a Tablet of the Law. "If I had only had the presence of mind to use these, I could have built the zeta-function machine much sooner, and others besides." A bit later in their conversation >[Turing] is hugging the //RCA Radio Tube Manual// to himself with one arm, doodling in a notebook with the other. Waterhouse thinks that really the //RCA Radio Tube Manual// is like a ball and chain holding Alan back. If he would just work with pure ideas like a proper mathematician he could go as fast as thought. As it happens, Alan has become fascinated by the incarnations of pure ideas in the physical world. The underlying math of the universe is like the light streaming in through the window. Alan is not satisfied with merely knowing that it streams in. He blows smoke into the air to make the light visible. He sits in meadows gazing at pine cones and flowers^^4^^, tracing the mathematical patterns in their structure, and he dreams about electron winds blowing over the glowing filaments and screens of radio tubes, and, in their surges and eddies, capturing something of what is going on in his own brain. Turing is neither a mortal nor a god. He is Antaeus^^5^^. That he bridges the mathematical and physical worlds is his strength and his weakness. ---- ^^1^^ [[Bletchley Park|http://www.bbc.co.uk/history/places/bletchley_park]] - Britain's main decryption establishment during World War II. Ciphers and codes of several Axis countries were decrypted including, most importantly, those generated by the German Enigma and Lorenz machines. ^^2^^ [[The RCA Receiving Tube Manual|http://www.tubebooks.org/tubedata/RC16.pdf]] - all 324 pages of it! [PDF] ^^3^^ - see [[zeta-function machine|http://tuxar.uk/turing/zeta-machine-riemann-hypothesis/]] and the Riemann Hypothesis. ([[GD link|https://drive.google.com/open?id=1239ulHa9k288fN6Sx-ee56UUVy8jsGW_5By_SBfMS3k]]). ^^4^^ - Turing's [[Watching the Daisies Grow & Fibonacci phyllotaxis|https://drive.google.com/open?id=1R5_cfaCQ6n02YqRH94zdGJmOAMYMHDo6]] ^^5^^ - From Wikipedia: [[Antaeus|https://en.wikipedia.org/wiki/Antaeus]] (from the Greek mythology - the half-giant son of Poseidon and Gaia) would challenge all passers-by to wrestling matches and remained invincible as long as he remained in contact with his mother, the earth [Gaia]. As Greek wrestling, like its modern equivalent, typically attempted to force opponents to the ground, he always won, killing his opponents. Antaeus fought Hercules as he was on his way to the Garden of Hesperides as his 11^^th^^ [[Labor|http://www.perseus.tufts.edu/Herakles/labors.html]]. Hercules realized that he could not beat Antaeus by throwing or pinning him. Instead, he held him aloft and then crushed him to death in a bear-hug.
<<list-links "[tag{!!title}]">>
<a href="resources/einstein_ambigram.gif"><img src="resources/einstein_ambigram.gif"></a> [1]
----
1- Ambigram from [[01101001|http://www.01101001.com/ambigrams/index.html]]. See [[other ambigrams|Ambigrams by Scott Kim]] by Scott Kim
American professor of psychology and affiliate professor of philosophy at the University of California, Berkeley.
<<list-links "[tag{!!title}]">>
A Buddhist joke: Question: What did the Buddhist monk ask of the hot-dog vendor? Answer: Make me one with everything.
!!!Upside-down ambigram <a href="./resources/scott_kim_mathematics.jpg" target="new"><img src="./resources/scott_kim_mathematics.jpg" width="70%" height="70%" /></a> !!!Left-right ambigram <a href="./resources/scott_kim_mirror.jpg" target="new"><img src="./resources/scott_kim_mirror.jpg" width="70%" height="70%" /></a>
Seymour Papert (the inventor of the programming language/environment Logo, and a participant on [[Edge|http://www.edge.org/]]) wrote [ext[an article|resources/AnExplorationintheSpaceofMathematicsEducations.html]] in 1996 on a 'different enough' "alternative math education" framework (even though he calls it a 'point' in the Math Education space), with a few interesting principles and dimensions: * __The power principle__ or "what comes first, using it or 'getting it'?" The natural mode of acquiring most knowledge is through use leading to progressively deepening understanding. Only in school is this order systematically inverted. * The principle of __project before problem__ is a similar/related inversion. Problems come up in the course of projects and are sometimes "solved" and sometimes "dissolved." It is an inversion order to define the goal of mathematics as problem-solving. ** It's not surprising that Neil Gershenfeld from the [[Center for Bits and Atoms|http://cba.mit.edu/]] (spawned from the MIT Media Lab) is advocating [[project based learning|Interdisciplinary Learning]] too. Papert was a founding faculty member of the Lab... * __New media open the door to new contents__. Of course it is not to be assumed that the shift of media has radical consequences in itself, but if the new media will be used to support the old content it will often do this badly since the content was defined for the old media ** For example: old content+media: written text on paper, vs. new content+media: simulations on computers ** [[Transplanted games|Transplanted games - new media but old content]] are a __bad example__, since they are not taking advantage of new media (computer technologies) (see what Robert Logan (and Marshall ~McLuhan) has to say on new media/language and content in his book [[The Sixth Language: Learning a Living in the Internet Age|New languages]]). * __The "thingness" principle__: object before operation. making entities (e.g., math functions) operational by giving them thing-like properties and by relating to them as things (e.g. defining/building, composing, transforming math functions). * __The principle of putting dynamics before statics__ (for example in physics). Papert claims that by 'thingifying' entities/concepts like gravity and velocity (i.e. allowing them to have properties and be manipulated as objects), dynamics can be grasped early and intuitively. ** Papert says that many teachers justifiably point out that one needs calculus to do dynamics seriously and calculus comes at the end of a prerequisite chain that runs something like arithmetic to algebra to calculus. He points out that there is truth in it insofar as it reflects the static nature of pre-computational media. And says: "to state a complex matter far too simply, calculus is a way of representing dynamic phenomena in the static medium of pencil and paper; it is 'hard' because the medium fights the message."
As part of my [[MA studies at Stanford|http://ldtprojects.stanford.edu/~hmark/index.html]], I designed and implemented a prototype of an online tutoring system incorporating some principles, capabilities and features, that would make learning more effective. I was delighted to see that [[the Khan Academy|The Khan Academy]] has implemented very similar capabilities in their online system as well. This project applies Cybernetic principles to Intelligent Tutoring systems. The system consists of a domain model including domain knowledge and skills. It also includes a desired learner performance model (or profile), which is continuously compared to the domain knowledge (both in terms of knowledge ans skills). This creates a cybernetic feedback loop, enabling the system to adjust and tailor the instruction to where the learner is, in relation to the domain model/profile. There is also an immediate 3D feedback given to the learner in terms of their performance level (mastery level dimension), their knowledge coverage (knowledge domain dimension), and their efficiency (time dimension). My system design spec can be found on the [[Stanford LDT site|http://ldtprojects.stanford.edu/~hmark/projects/Haggai Mark - Second Order Feedback system spec.pdf]] or on the [ext[local server|./resources/Haggai Mark - Second Order Feedback system spec.pdf]].
From Ian Stewart's (as the Brits say:) //lovely// book //Professor Stewart's Hoard of Mathematical Treasures//: * Did Erwin Schrödinger have a cat? ** Yes and no.^^*^^ * Did Werner Heisenberg have a cat? ** I’m not sure. * Did Kurt Gödel have a cat? ** If he did, we can’t prove it. * Did Fibonacci have a cat? ** He certainly had a lot of rabbits. * Did René Descartes have a cat? ** He thought he did. * Did ~Augustin-Louis Cauchy have a cat? ** That’s a complex question. * Did Georg Bernhard Riemann have a cat? ** That hypothesis has not yet been proved. * Did Albert Einstein have a cat? ** One of his relatives did. * Did Luitzen Brouwer have a cat? ** Well, he didn’t not have one. * Did William Feller have a cat? ** Probably. * Did Ronald Aylmer Fisher have a cat? ** The null hypothesis is rejected at the 95% level. ---- ^^*^^ another take on Schrödinger's cat (from Terry Pratchett): >Technically, a cat locked in a box may be alive or it may be dead. You never know until you look. In fact, the mere act of opening the box will determine the state of the cat, although in this case there were three determinate states the cat could be in: these being Alive, Dead, and Bloody Furious.
This is an oldie but goodie, which could be (and has been :) extended to other professions: A few professionals were asked to prove (or disprove, if they dare :-) the //conjecture// which states that `ALL odd numbers are also prime numbers.` * The mathematician reasoned: ** 3 is a prime, 5 is a prime, and by mathematical induction: all odd numbers are prime. * The physicist stated: ** 3 is a prime, 5 is a prime, 7 is a prime, 9 ... is a measurement error, 11 is a prime, and therefore the data supports it: all odd numbers are prime. * The engineer said: ** 3 is a prime, 5 is a prime, 7 is a prime, 9 is a prime, 11 is a prime, and therefore it's clear that all odd numbers are prime. * The programmer calculated: ** 3 is a prime, 5 is a prime, 7 is a prime, 7 is a prime, 7 is a prime, 7 is a prime, 7 is a prime, 7 is a prime, ... and therefore: all odd numbers are prime.
This is [[a paper by Nick Bostrom|http://www.simulation-argument.com/simulation.pdf]] (see [[GD link|https://drive.google.com/open?id=1sw2A5NpFrbj3H9Kglivghm6ooUtzCymG]]). The abstract: This paper argues that at least one of the following propositions is true: # the human species is very likely to go extinct before reaching a “posthuman” stage; # any posthuman civilization is extremely unlikely to run a significant number of simulations of their evolutionary history (or variations thereof); # we are almost certainly living in a computer simulation. It follows that the belief that there is a significant chance that we will one day become posthumans who run ancestor ‐ simulations is false, unless we are currently living in a simulation. A number of other consequences of this result are also discussed. Nothing new under the sun? see [[Sallustius]]'s take on [[the nature of reality|One may call the world a myth, in which bodies and things are visible, but souls and minds hidden...]]
<<list-links "[tag{!!title}]">>
<<list-links "[tag{!!title}]">>
known for his Science Fiction writing.
<<list-links "[tag{!!title}]">>
From the online book [["The Art of Unix Programming"|https://homepage.cs.uri.edu/~thenry/resources/unix_art/ch01s09.html]] by Eric Steven Raymond. Modified as a possible end-of-course email/message to my students in High School. In programming, as in life, when you know what the right thing to do is, do it — this may look like more work in the short term, but it's the path of least effort (and bad consequences) in the long run. Only if you don't know what the right thing is, do the minimum necessary to get the job done, at least until you figure out what the right thing is. To "do programming right" (and this applies to living life, too :), you have to be committed to excellence. You have to believe that software design is a craft worth all the intelligence, creativity, and passion you can muster. Otherwise you won't look past the easy, stereotyped ways of approaching design and implementation; you'll rush into coding when you should be thinking. You'll carelessly complicate when you should be relentlessly simplifying — and then you'll wonder why your programs are "complex and ugly" and why debugging and improving is so hard. To "do programming right", you have to value your own time enough not to waste it. If someone has already solved a problem once, don't let pride or politics suck you into solving it a second time rather than re-using. When reusing, give credit, be honest, stay on the right side of the law. And don't work harder than you have to; work smarter instead, and save the extra effort for when you need it. Lean on your creativity, develop tools and automate everything you can. Software design and implementation should be a joyous art, a kind of high-level play. If this notion seems "strange" to you, stop and think; ask yourself what you've forgotten. Why did you decide to learn to program in the first place? You must have thought software was "fun" and worthy of your time and effort once.... To do programming right, you need to care. You need to value and appreciate intelligence, creativity, and beauty. You need to play. You need to be willing to explore and be playful. I hope you'll develop this attitude to programming and to the rest of your life. And I hope that learning to program will help you cultivate it. For life. """ """ (see also [[More words of encouragement on the road (code? :) ahead]]). (see also [[A few words of encouragement (and advice :)]]).
<<list-links "[tag[Authentic Happiness]!tag[book]]">> I was drawn to this book by an [ext[article in the NY Times|resources/what-if-the-secret-to-success-is-failure.html]] about education and character (or character education). When I was studying for my [[MA degree at the Stanford University School of Education|http://ldtprojects.stanford.edu/~hmark/]], I was intrigued by work done by Ann L. Brown on [ext[metacognition|resources/Brown 94 - advancement of learning.pdf]]. I was very interested in the question of whether ''metacognitive skills'' can be taught, and if so how? Since I studied in the Learning, Design, and Technology program at Stanford, I was thinking of how technology could help, if indeed metacognitive skills could be taught to learners. Similarly, what intrigued me in the article and the book was the question of whether ''character'' can be taught. The [[tests and surveys in this book can be found online|http://www.authentichappiness.sas.upenn.edu/Default.aspx]].
<<list-links "[tag{!!title}]">>
In an [[animated and impassioned TED Talk|https://www.youtube.com/watch?v=IDS-ieLCmS4]], [[Barry Schwartz|https://en.wikipedia.org/wiki/Barry_Schwartz_(psychologist)]] dives into the question "How do we do the right thing?" With help from collaborator [[Kenneth Sharpe|https://www.swarthmore.edu/profile/kenneth-sharpe]], he shares stories that illustrate the difference between following the rules and truly choosing wisely. Both of them wrote [[a book titled Practical Wisdom: The Right Way to Do the Right Thing|https://www.swarthmore.edu/sites/default/files/assets/documents/user_profiles/ksharpe1/PW%20Cover%20and%20Blurb.pdf]]. (Here's [[an overview of Aristotelian ethics (and practical wisdom)|https://plato.stanford.edu/entries/aristotle-ethics/]]) So there is among many people a kind of collective dissatisfaction with the way things are working, with the way our institutions run. [...] There are two kinds of responses that we make to this sort of general dissatisfaction. If things aren't going right, the first response is: let's make more rules, let's set up a set of detailed procedures to make sure that people will do the right thing. [For example:] Give teachers scripts to follow in the classroom,[..., or] Give judges a list of mandatory sentences to impose for crimes, so that you don't need to rely on judges using their judgment,[..., or] Impose limits on what credit card companies can charge in interest and on what they can charge in fees. More and more rules to protect us against an indifferent, uncaring set of institutions we have to deal with. Or -- or maybe and -- in addition to rules, let's see if we can come up with some really clever incentives so that, even if the people we deal with don't particularly want to serve our interests it is in their interest to serve our interest -- the magic incentives that will get people to do the right thing even out of pure selfishness. So [For example:] we offer teachers bonuses if the kids they teach score passing grades on these big test scores that are used to evaluate the quality of school systems. Rules and incentives -- "sticks" and "carrots." [And another example:] We passed a bunch of rules to regulate the financial industry in response to the recent collapse. There's the ~Dodd-Frank Act, there's the new Consumer Financial Protection Agency [...] In addition, we are struggling to find some way to create incentives for people in the financial services industry that will have them more interested in serving the long-term interests even of their own companies, rather than securing short-term profits. So if we find just the right incentives, they'll do the right thing -- as I said -- selfishly, and if we come up with the right rules and regulations, they won't drive us all over a cliff. But what we believe, and what we argue in the book, is that there is no set of rules, no matter how detailed, no matter how specific, no matter how carefully monitored and enforced, there is no set of rules that will get us what we need. Why? Because [for example,] bankers are smart people. And, like water, they will find cracks in any set of rules. You design a set of rules that will make sure that the particular reason why the financial system "almost-collapse" can't happen again. It is naive beyond description to think that having blocked this source of financial collapse, you have blocked all possible sources of financial collapse. So it's just a question of waiting for the next one and then marveling at how we could have been so stupid as not to protect ourselves against that. What we desperately need, beyond, or along with, better rules and reasonably smart incentives, is we need virtue. We need character. We need people who want to do the right thing. And in particular, the virtue that we need most of all is the virtue that Aristotle called "practical wisdom." Practical wisdom is the moral will to do the right thing and the moral skill to figure out what the right thing is. So Aristotle was very interested in watching how the craftsmen around him worked. And he was impressed at how they would improvise novel solutions to novel problems -- problems that they hadn't anticipated. So one example is he sees these stonemasons working on the Isle of Lesbos, and they need to measure out round columns. Well if you think about it, it's really hard to measure out round columns using a ruler. So what do they do? They fashion a novel solution to the problem. They created a ruler that bends, what we would call these days a tape measure -- a flexible rule, a rule that bends. And Aristotle said, "Hah, they appreciated that sometimes to design rounded columns, you need to bend the rule." And Aristotle said often in dealing with other people, we need to bend the rules. Dealing with other people demands a kind of flexibility that no set of rules can encompass. Wise people know when and how to bend the rules. Wise people know how to improvise. [...] they are kind of like jazz musicians. The rules are like the notes on the page, and that gets you started, but then you dance around the notes on the page, coming up with just the right combination for this particular moment with this particular set of fellow players. So for Aristotle, the kind of rule-bending, rule exception-finding and improvisation that you see in skilled craftsmen is exactly what you need to be a skilled moral craftsman. And in interactions with people, almost all the time, it is this kind of flexibility that is required. A wise person knows when to bend the rules. A wise person knows when to improvise. And most important, a wise person does this improvising and rule-bending in the service of the right aims. If you are a rule-bender and an improviser mostly to serve yourself, what you get is ruthless manipulation of other people. So it matters that you do this wise practice in the service of others and not in the service of yourself. And so the will to do the right thing is just as important as the moral skill of improvisation and exception-finding. Together they comprise practical wisdom, which Aristotle thought was the master virtue. [[At another talk, at Google, Barry Schwartz summarized practical wisdom and wise people|https://www.youtube.com/watch?v=y2f17aNrKag]] thusly: * Wise people know when and how to make the exception to every rule. * Wise people know when and how to improvise. ** We talk about wisdom as a kind of moral jazz. There are notes on the page, if you like. Those are the rules, but they're just guidelines. And what makes great jazz is not that you play the notes on the page, it's how you deviate from the notes on the page. You can do that well or you can do that badly. Wise people are good jazz musicians. * Wise people know how to find the mean, which is not the arithmetic average. ** It's what Aristotle had in mind when he talked about how courage was the mean between cowardice and recklessness. Now where is the mean between cowardice and recklessness? The answer is: it depends. It depends on the context. It depends on the circumstances. There is no formulaic way to figure out what the mean is. * Wise people know how to choose among virtues when they conflict. ** Wise people figure out how to do it and the point of balance, again, as Aristotle emphasized, depends on who you're dealing with, what the circumstances are. * Wise people know how to put themselves in other people's places. ** They can see the world as other people see the world. And they can feel what other people are feeling. Empathic understanding is an essential ingredient of wisdom. It's something that takes experience to learn. * a wise person uses these skills in pursuit of the right aims, to serve other people and not to serve him or herself. ** If you use all of these skills to serve yourself, you become a Machiavellian manipulator and that's not what Aristotle thought a virtuous person was like. * And last, a wise person is made, not born. ** everybody has the capacity to develop these characteristics, but *** it takes experience. *** It takes trial and error. *** It takes making mistakes and getting wiser as a result of learning from your mistakes. ** Nobody is born with the magic gift of wisdom. So, too many rules undermine the development of the skill that you need to be wise and too much reliance on incentives undermines the will that you need to be wise. And again, all of these efforts to reform systems were well-intentioned. They were not designed to make the systems worse. They were designed to make the systems better. And they may make the systems better in the short run, but they create a problem which guarantees that the systems will be worse in the long run.
In an impassioned [[TED Talk|https://www.youtube.com/watch?v=3B_1itqCKHo]], [[Barry Schwartz|https://en.wikipedia.org/wiki/Barry_Schwartz_(psychologist)]], a [[psychologist from Swarthmore|https://www.swarthmore.edu/SocSci/bschwar1/]], described the concept he coined Idea Technology. Compare this to [[Raymund Smullyan's way of expressing it in a biblical fable|The power of ideas - free will]]. From Schwartz's talk transcript: [when I'm talking about Idea Technology] I'm not talking about the technology of things, profound though that is. I'm talking about another technology. I'm talking about the technology of ideas. ... In addition to creating things, science creates ideas. Science creates ways of understanding. And in the social sciences, the ways of understanding that get created are ways of understanding ourselves. And they have an enormous influence on how we think, what we aspire to, and how we act. If you think your poverty is God's will, you pray. If you think your poverty is the result of your own inadequacy, you shrink into despair. And if you think your poverty is the result of oppression and domination, then you rise up in revolt. Whether your response to poverty is resignation or revolution, depends on how you understand the sources of your poverty. This is the role that ideas play in shaping us as human beings, and this is why idea technology may be the most profoundly important technology that science gives us. And there's something special about idea technology, that makes it different from the technology of things. With things, if the technology sucks, it just vanishes, right? Bad technology disappears. With ideas -- false ideas about human beings will not go away if people believe that they're true. Because if people believe that they're true, they create ways of living and institutions that are consistent with these very false ideas. And that's how the industrial revolution created a factory system in which there was really nothing you could possibly get out of your day's work, except for the pay at the end of the day. Because the father -- one of the fathers of the Industrial Revolution, Adam Smith -- was convinced that human beings were by their very natures lazy, and wouldn't do anything unless you made it worth their while, and the way you made it worth their while was by incentivizing, by giving them rewards. That was the only reason anyone ever did anything. So we created a factory system consistent with that false view of human nature. But once that system of production was in place, there was really no other way for people to operate, except in a way that was consistent with Adam Smith's vision. So the work example is merely an example of how false ideas can create a circumstance that ends up making them true. It is not true that you "just can't get good --help-- [work] anymore." It is true that you "can't get good --help-- [work] anymore" when you give people work to do that is demeaning and soulless. And interestingly enough, Adam Smith -- the same guy who gave us this incredible invention of mass production, and division of labor -- understood this. He said, of people who worked in assembly lines, of men who worked in assembly lines, he says: "He generally becomes as stupid as it is possible for a human being to become." Now, notice the word here is "become." "He generally becomes as stupid as it is possible for a human being to become." Whether he intended it or not, what Adam Smith was telling us there, is that the very shape of the institution within which people work creates people who are fitted to the demands of that institution and deprives people of the opportunity to derive the kinds of satisfactions from their work that we take for granted. The thing about science -- natural science -- is that we can spin fantastic theories about the cosmos, and have complete confidence that the cosmos is completely indifferent to our theories. It's going to work the same damn way no matter what theories we have about the cosmos. But we do have to worry about the theories we have of human nature, because human nature will be changed by the theories we have that are designed to explain and help us understand human beings. The distinguished anthropologist, Clifford Geertz, said, years ago, that human beings are the "unfinished animals." And what he meant by that was that it is only human nature to have a human nature that is very much the product of the society in which people live. That human nature, that is to say our human nature, is much more created than it is discovered. We design human nature by designing the institutions within which people live and work. And at the end Schwartz implores the audience ([[TED attendees|https://www.ted.com/about/conferences]]): >And so you people -- pretty much the closest I ever get to being with masters of the universe -- you people should be asking yourself a question, as you go back home to run your organizations. >Just what kind of human nature do you want to help design?
Inspired by Clifford Pickover's article "Beauty and the Bits", in his book "Mazes for the Mind".
As Pickover writes:
>The humble bits that lie at the very foundation of computing have a sepecial beauty all their own.
!!!Basic binary bits background
Here are the "truth tables" for the basic logic operations (AND, OR, XOR, NOT):
`
AND | 0 1 OR | 0 1 XOR | 0 1 NOT | 0 1
----+----- ---+---- ----+---- ----+----
0 | 0 0 0 | 0 1 0 | 0 1 | 1 0
1 | 0 1 1 | 1 1 1 | 1 0
`
Here are some examples of binary numbers and bit operations.
"|" is the logical OR operation (bit by bit)
"~" is the logical NOT operation
`
print "n1\tn2\t n1 | n2 ~n1"
print "------------------------------"
for n1 in [0, 7, 9, 6]:
for n2 in [1, 2, 3, 4, 5, 6]:
bin_n1 = bin(n1).lstrip('-0b').zfill(4)
bin_n2 = bin(n2).lstrip('-0b').zfill(4)
n1_or_n2 = bin(n1 | n2).lstrip('-0b').zfill(4)
comp_bin_list_n1 = [ str((1 + int(b)) % 2) for b in bin_n1]
comp_bin_n1 = ''.join(comp_bin_list_n1)
print "%s\t%s\t %s\t %s" % (bin_n1, bin_n2, n1_or_n2, comp_bin_n1)
resulting in:
n1 n2 n1 | n2 ~n1
------------------------------
0000 0001 0001 1111
0000 0010 0010 1111
0000 0011 0011 1111
0000 0100 0100 1111
0000 0101 0101 1111
0000 0110 0110 1111
0111 0001 0111 1000
0111 0010 0111 1000
0111 0011 0111 1000
0111 0100 0111 1000
0111 0101 0111 1000
0111 0110 0111 1000
1001 0001 1001 0110
1001 0010 1011 0110
1001 0011 1011 0110
1001 0100 1101 0110
1001 0101 1101 0110
1001 0110 1111 0110
0110 0001 0111 1001
0110 0010 0110 1001
0110 0011 0111 1001
0110 0100 0110 1001
0110 0101 0111 1001
0110 0110 0110 1001
`
!!Displaying some beauties with the bits
Equipped with the above background, one can create some interesting and unexpected patters.
If you take a display area of, say, 256 rows by 256 columns, you can treat each location/coordinate pair (x, y) or (column, row) as a pixel which will be colored based on a certain formula applied to its 2 coordinate numbers.
And some beautiful bit twiddling results:
`
Basic bit twiddling Enhanced bit twiddling
pix_color = (col | row) % 255 pix_color = ((col | row) | (row * col)) % 255
`
<a href="resources/BaB enhanced.png" target="new"><img src="resources/BaB enhanced.png" width="50%" height="50%" /></a>
<a href="resources/resources/BaB basic.png" target="new"><img src="resources/BaB basic.png" width="50%" height="50%" /></a>
And a Python implementation:
`
import image
img = image.Image("empty_square.png")
win = image.ImageWin(img.getWidth(), img.getHeight())
img.setDelay(1, 100) # fast update - setDelay(0) turns off animation
img.draw(win)
for row in range(img.getWidth()):
for col in range(img.getHeight()):
pix_color = (col | row) % 255 # basic Pickover
pix_color = ((col | row) | (row * col)) % 255 # enhanced Pickover
new_pixel = image.Pixel(color + 60, color + 20, color)
img.setPixel(col, row, new_pixel)
`
And the possibilities are endless:
`
pix_color = ((col | row) | (col - row)) % 255 pix_color = (~(col | row) | ~(row * col)) % 255
`
<a href="resources/BaB enhanced enhanced.png" target="new"><img src="resources/BaB enhanced enhanced.png" width="50%" height="50%" /></a>
<a href="resources/resources/BaB enhanced2.png" target="new"><img src="resources/BaB enhanced2.png" width="50%" height="50%" /></a>
From the short essay [[Beginner's Mind|http://www.symmetrymagazine.org/sites/default/files/legacy/pdfs/200703/essay.pdf]] by Jennifer Ouellette. >Several years ago I earned my black belt in jujitsu. Before tying the belt around my waist, the grand master had me don my old white belt, which designates a beginner. He then instructed me to look into a mirror and reflect on what it had been like to walk onto the dojo mat for the first time. The reasoning behind the ceremony is that in order to effectively teach a beginner any given technique, an instructor must be able to break it down into its most basic components. Ergo, it’s vital to remember what it was like to know nothing about the technique at all. >The same is true when it comes to communicating science. And the same is true when teaching (Computer Science - like I do - or anything else).
From [[BrainPickings|https://www.brainpickings.org/2012/05/02/a-liberal-decalogue-bertrand-russell/]] (reviewing the third volume of //The Autobiography of Bertrand Russell: 1944-1969//): Perhaps the essence of the Liberal outlook could be summed up in a new decalogue, not intended to replace the old one but only to supplement it. The Ten Commandments that, as a teacher, I should wish to promulgate, might be set forth as follows: # Do not feel absolutely certain of anything. # Do not think it worth while to proceed by concealing evidence, for the evidence is sure to come to light. # Never try to discourage thinking for you are sure to succeed. # When you meet with opposition, even if it should be from your husband or your children, endeavor to overcome it by argument and not by authority, for a victory dependent upon authority is unreal and illusory. # Have no respect for the authority of others, for there are always contrary authorities to be found. # Do not use power to suppress opinions you think pernicious, for if you do the opinions will suppress you. #Do not fear to be eccentric in opinion, for every opinion now accepted was once eccentric. # Find more pleasure in intelligent dissent than in passive agreement, for, if you value intelligence as you should, the former implies a deeper agreement than the latter. # Be scrupulously truthful, even if the truth is inconvenient, for it is more inconvenient when you try to conceal it. # Do not feel envious of the happiness of those who live in a fool’s paradise, for only a fool will think that it is happiness.
(or "shouldn't you put your money where your mouth is?") It is said that in Niels Bohr's (the great Danish physicist) house there was a horseshoe hanging over one door, and a friend asked him, “What’s this all about?” Bohr answered, “Well, horseshoes are supposed to bring good luck, so we put it up there.” The friend then said, “Come now — surely you don’t believe it brings good luck, do you?” Bohr laughed and said, “Of course not!” And then he added, “But they say it works even if you don’t believe in it.” or as Andrew W. Mathis said: > It is bad luck to be superstitious. """ """ This reminds me of a story about the philosopher [[Sidney Morgenbesser|https://en.wikiquote.org/wiki/Sidney_Morgenbesser]]: A few weeks before his death, he asked another Columbia philosopher, David Albert, about God. "Why is God making me suffer so much?" he asked. "Just because I don't believe in him?"
The creator of Microsoft.
<<list-links "[tag{!!title}]">>
In his excellent (1997) book [[Billions and Billions: Thoughts on Life and Death at the Brink of the Millennium|https://en.wikipedia.org/wiki/Billions_and_Billions]], Carl Sagan writes in the introduction:
>THE POWER AND BEAUTY OF QUANTIFICATION
>>There are some . . . who think that the number of [grains of] sand is infinite. . . . There are some who, without regarding it as infinite, yet think no number has been named which is great enough. . . . But I will try to show you [numbers that] exceed not only the number of the mass of sand equal to the Earth filled up ... but also that of a mass equal in magnitude to the Universe.
::: -- ARCHIMEDES (CA. 288-212 B.C.),
>
>I never said it. Honest. Oh, I said there are maybe 100 billion galaxies and 10 billion trillion stars. It's hard to talk about the Cosmos without using big numbers. I said "billion" many times on the Cosmos television series, which was seen by a great many people. But I never said "billions and billions." For one thing, it's too imprecise. How many billions are "billions and billions"? A few billion? Twenty billion? A hundred billion? "Billions and billions" is pretty vague^^1^^. When we reconfigured and updated the series, I checked—and sure enough, I never said it.
>
>But Johnny Carson—on whose Tonight Show I'd appeared almost thirty times over the years—said it.
>He'd dress up in a corduroy jacket, a turtleneck sweater, and something like a mop for a wig. He had created a rough imitation of me, a kind of Doppelganger, that went around saying "billions and billions" on late-night television. It used to bother me a little to have some simulacrum of my persona wandering off on its own, saying things that friends and colleagues would report to me the next morning. (Despite the disguise, Carson—a serious amateur astronomer—would often make my imitation talk real science.) Astonishingly, "billions and billions" stuck. People liked the sound of it. Even today, I'm stopped on the street or on an airplane or at a party and asked, a little shyly, if I wouldn't—just for them—say "billions and billions."
>
>"You know, I didn't actually say it," I tell them.
>"It's okay," they reply. "Say it anyway.”
>[...]
>I'm still quoted as uttering this simple-minded phrase in computer magazines^^2^^ ("As Carl Sagan would say, it takes billions and billions of bytes"), newspaper economics primers, discussions of players' salaries in professional sports, and the like.
>
>For a while, out of childish pique, I wouldn't utter or write the phrase, even when asked to. But I've gotten over that. So, for the record, here goes:
>
>''"Billions and billions.”''
----
^^1^^ - The phrase has, however, now become a humorous fictitious number—[[the Sagan|https://en.wikipedia.org/wiki/Indefinite_and_fictitious_numbers]].
^^2^^ - In late-1993, Carl Sagan learnt [[the magazine MacWEEK|https://en.wikipedia.org/wiki/MacWEEK]] had mentioned that Apple's forthcoming computer, the Power Macintosh 7100, had been given a codename of "Carl Sagan" — the joke being that they would sell "billions and billions."
In his interesting article [["The Unreasonable Effectiveness of Mathematics"|http://www.dartmouth.edu/~matc/MathDrama/reading/Hamming.html]], [[Richard Hamming]] makes some thoughtful arguments [[On why Math works for us]] and [[On scientific vs. religious explanation]]. In homage to Hamming, and his brilliant idea around correcting errors in transmission of binary information, I've implemented a [[1 bit error correcting logic circuit|http://employees.org/~hmark/math/logicsim/logicsim_hamming3.html]] using [[LogicSim|http://www.tetzl.de/java_logic_simulator.html]]. The logic simulator is ~OpenSource, and produces Java applets, so it can be used ubiquitously. It allows for [[hierarchical design of binary logic circuits|http://employees.org/~hmark/math/logicsim/logicsim_hamming3_hierarchy.html]] (i.e. building "parts" or logic "integrated circuits", that can be used in larger and more complex designs, etc.). As the notes on the [[simulation page|http://ldt.stanford.edu/~hmark/math/logicsim/logicsim_hamming3_hierarchy.html]] indicate, this is an error correcting circuit for single errors, and it achieves it by adding 3 more code bits to the 4 data bits transmitted. Obviously, if more errors need to be corrected, more code bits need to be added (as in many other areas in life, there is no free lunch in information processing).
<<list-links "[tag{!!title}]">>
<br> ``` What an astonishing thing a book is. it's a flat object made from a tree with flexible parts on which are imprinted lots of funny dark squiggles. But one glance at it and you're inside the mind of another person, maybe somebody dead for thousands of years. Across the millennia, an author is speaking clearly and silently inside your head, directly to you. Writing is perhaps the greatest of human inventions, binding together people who never knew each other, citizens of distant epochs. ``` ``` Books break the shackles of time. A book is proof that humans are capable of working magic. ``` : - Carl Sagan (Cosmos, 1980) ``` People disappear when they die. Their voice, their laughter, the warmth of their breath. Their flesh. Eventually their bones. All living memory of them ceases. This is both dreadful and natural. Yet for some there is an exception to this annihilation. For in the books they write they continue to exist. We can rediscover them. Their humor, their tone of voice, their moods. Through the written word they can anger you or make you happy. They can comfort you. They can perplex you. They can alter you. All this, even though they are dead. Like flies in amber, like corpses frozen in ice, that which according to the laws of nature should pass away is, by the miracle of ink on paper, preserved. It is a kind of magic. ``` : - Diane Setterfield (The Thirteenth Tale, 2006) ``` I cannot remember the books I have read any more than the meals I have eaten; even so, they have made me. ``` : - Ralph Waldo Emerson ``` For readers, what they read is where they've been, and their collections [of books] are evidence of the trek. For writers, the personal library is the toolbox which contains the day's necessary implements of construction — there is no such thing as a skillful writer who is not also a dedicated reader — as well as a towering reminder of the task at hand: to build something worthy of being bound and occupying a space on those shelves, on all shelves... Since bibliophiles will acknowledge the absurdity, the obese impracticality of gathering more books than there are days to read them, one's collection must be about more than remembering: it must be about expectation also. Your personal library, swollen and hulking about you, is the promise of betterment and pleasure to come, a giddy anticipation, a reminder of the happy work left to do, a prompt for those places to which your intellect and imagination want to roam. ``` : - William Giraldi (The Bibliophile, 2018) <<list-links "[tag[book]]">>
http://worrydream.com/
<html>
<table>
<tr>
<td width="40%">
<a href="./resources/bret.png" target="new"><img src="./resources/bret.png" width="100%" height="100%" /></a>
</td>
<td width="60%">
<pre>
In the schools, I trained in the way of the Electron.
On the streets, I learned the way of the Algorithm
And I mastered these paths, but they were false paths. Their followers knew only the Yang of Technology, and worshiped the Code. But technology has no soul, and code no conscience. And I despaired.
Yet I sought, and after many seasons, I found the Yin of Design. It spoke of people, not things. I studied the way of the Interface, of human perception and understanding.
And I mastered this path, but it was a false path. Its followers were taught to answer questions. They could not question the questions themselves. And I despaired.
Yet I sought, and I thought, and I pursued my own path. And with time, I was enlightened.
The True Way transcends the minutiae of Skill. There is no "Technology”. There is no "Design". There is only a vision of how humanity could be, and the relentless resolve to make it so. The rest is details.
</pre>
</td>
</tr>
</table>
</html>
<<list-links "[tag{!!title}]">>
Biologist, Schumacher College, U.K.; author of Nature's Due: Healing Our Fragmented Culture.
<<list-links "[tag{!!title}]">>
[[Brian Kernighan|http://en.wikipedia.org/wiki/Kernighan]]
<<list-links "[tag{!!title}]">>
<<list-links "[tag{!!title}]">>
In an interesting [[TED talk|http://ed.ted.com/lessons/the-game-layer-on-top-of-the-world-seth-priebatsch]], Seth Priebatsc, founder of the [[SCVNGR platform|https://en.wikipedia.org/wiki/SCVNGR]]^^1^^ described a few game-inspired principles which could significantly impact our behavior. His first observation was that the "social layer" of connectivity to, and relationships with people has been built in the last decade (2000-2010), and is mainly defined by the [[Open Graph|http://ogp.me/]] by Facebook. He states that in the next decade (2010-2020) the "game layer" which is all about influencing behavior, will be built. This echoes Nir Eyal's ideas about [[creating habits and influencing behaviors|http://www.nirandfar.com/2012/03/how-to-design-behavior.html]] (in good //and// bad ways/means) through products and services. In his talk Priebatsc lists and describes a few principles: * The appointment dynamic - in which to succeed one has to do something predetermined at a predefined time (his examples: social "Happy Hour", taking medicine, playing Farmville) * The influence dynamic - in which one player has the ability to modify the behavior of another player through social pressure (his examples: prestigious credit cards, publicized online game mastery levels, grades and titles/roles in school and work) * Progression dynamic - in which success is measured and displayed granularly, indicating completing itemized tasks (his examples: the ~LinkedIn profile completion status indicator, leveled-up/super-powered characters in games, membership and loyalty tiers and progressions) * Communal discovery dynamic - in which an entire community or group rallies to work together to solve a challenge or problem (his examples: [[Digg|http://digg.com/]] (where the community tries to find/source the "best news/story"), ~McDonald's Monopoly, DARPA Balloon location) ---- ^^1^^ - SCVNGR has been used as a tool for orientation for prospective and new students to college campuses, but it has also been used for orientation to campus libraries. Rather than having a traditional tour guide approach to orientation, colleges and libraries have used the SCVNGR application to allow students/patrons to visit the places they need to know but through an active, collaborative group activity.
Can mathematics be used to extract qualitative predictions from physical laws - or, for that matter, useful laws from data - automatically? Perhaps, but the omens aren't auspicious. With Gödel's theorem^^1^^ (the existence of true statements that can't be proved formally) and the concepts of computational complexity (the existence of many natural problems that can't be solved by practical algorithms) and chaos (the existence of natural equations that can't be solved systematically), mathematics has identified limits to its own power. -- from [[Reasonably effective: I. Deconstructing a miracle|http://ned.ipac.caltech.edu/level5/March07/Wilczek/Wilczek.html]] by [[Frank Wilczek]] ---- ^^1^^ See [ext[Gödel's Second Incompleteness Theorem Explained in Words of One Syllable|resources/Boolos-godel-in-single-syllables.pdf]] or compare to [[The world's shortest explanation of Gödel's theorem]] (alternative, searchable spellings for Gödel: Godel, Goedel)
I came across this [[pantoun|https://www.poets.org/poetsorg/text/pantoum-poetic-form]]^^1^^, which reminded me of the [[Exercises in Style - Raymond Queneau]], in terms of experimentation and playfulness. The repetition-with-variation-and-refinement is appealing to me both because of implications and analogies to education/learning, and because of the successive/layered fleshing out of details, not unlike the process of top-down design and hierarchical decomposition, often done in software programming^^2^^. """ Tonight you’re loaning Billy your car, a brand-new seal-gray Volkswagen Passat with four doors, though last week at 3 A.M., he stole your canoe, and sank it in the autumn sea, then swam ashore. Tonight you’re lending Billy your car—it’s brand-new— and he’s a well-meaning, blue-eyed Byronic drinking man who last week, at 3 A.M., stole your beached canoe, and when it sank he blamed it on a dolphin. A well-meaning, blue-eyed, Byronic, hard-drinking man whose phone calls you take, no matter the hour, who sank your canoe and blamed it on a dolphin, and the young man with him, whom the sea sadly devoured, so you’ll always take Billy’s call, no matter the hour. Because, you sigh, his mother’s dying, too, and he’s drinking again. He’s no longer a young man (he’s sad and he’s drowning), and neither are you, and all friends sometimes sin. Besides, you sigh, his mother’s dying, too, that’s why he’s drinking. She wasn’t a beauty—she came on to you long ago. And he’s not a young man; he’s drunk and he’s drowning. So you press the phone to your cheek, stare out the dark window. Who hasn’t come on to you? (Who wasn’t lovely long ago?) (Even Billy did; his tragic need, his blank blue eyes.) You press the phone to cheek, stare out the dark window, and listen to him make a mess of our peaceful lives. Now back in bed, we return to our disrupted romance. Although last week, at 3 A.M., he stole your canoe, you set a sinking man adrift in the sea of second chance: tonight you’ve loaned Billy your car again, brand-new. """ ---- ^^1^^ - pantoum - from [[Dictionary.com|http://www.dictionary.com/browse/pantoum]] (orig. pantoun, or pantun) - a Malay verse form consisting of an indefinite number of quatrains with the second and fourth lines of each quatrain repeated as the first and third lines of the following one. ^^2^^ - from [[Poets.org|https://www.poets.org/poetsorg/text/pantoum-poets-glossary]]: A pantoum typically begins: """ Line 1: A Line 2: B Line 3: C Line 4: D Line 5: B Line 6: E Line 7: D Line 8: F Line 9: E Line 10: G Line 11: F Line 12: H """ It is customary for the second and fourth lines in the last stanza of the poem to repeat the first and third lines of the initial stanza, so that the whole poem circles back to the beginning, like a snake eating its tail. Now, if this doesn't look like software description and decomposition/refinement, then what does? :) Also, the last sentence above (referring to a snake) is a common image to describe/imagine the technique of recursion (see the mentioning of [[Ouroboros in the definition of recursion|https://en.wikipedia.org/wiki/Recursion]] in software development -- recursion being a software problem solving technique, where a function/method/procedure calls itself in order to solve the problem.
Sounds like terrible advice, but hear this guy out ([[Chad Fowler in his book The Passionate Programmer|https://pragprog.com/titles/cfcar2/the-passionate-programmer]]) He has a very good point, which boils down to: if you swallow your pride/ego, open your ears, eyes, and mind, it will pay off greatly. (This has been my experience as well :) and if you do it wholeheartedly, it "grows on you", and you start to enjoy these kinds of environments/people, even look forward to being in/with them.) So here it is, simple but hard: ''Be the worst guy in every team you're in.'' Legendary jazz guitarist Pat Metheny has a stock piece of advice for young musicians, which is "Always be the worst guy in every band you're in.” >Before starting my career in information technology, I was a professional jazz and blues saxophonist. As a musician, I had the good fortune of learning this lesson early on and sticking to it. Being the worst guy in the band means always playing with people who are better than you. > >Now, why would you always choose to be the worst person in a band? "Isn't it unnerving?" you ask. Yes, it's extremely unnerving at first. As a young musician, I would find myself in situations where I was so obviously the worst guy in the band that I was sure I would stick out like a sore thumb. I'd show up to a gig and not even want to unpack my saxophone for fear I’d be forcefully ejected from the bandstand. I'd find myself standing next to people I looked up to, expected to perform at their level—sometimes as the lead instrument! > >Without fail (thankfully!), something magical would happen in these situations: I would fit in. I wouldn't stand out among the other musicians as a star. On the other hand, I wouldn't be obviously outclassed, either. This would happen for two reasons. The first reason is that I really wasn't as bad as I thought. We'll come back to this one later. > >The more interesting reason that I would fit in with these superior musicians—my heroes, in some cases—is that my playing would transform itself to be more like theirs. I'd like to think I had some kind of superhuman ability to morph into a genius simply by standing next to one, but in retrospect I think it's a lot less glamorous than that. It was more like some kind of instinctual herd behavior, programmed into me. It's the same phenomenon that makes me adopt new vocabulary or grammatical habits when I'm around people who speak differently than me. When we returned from a year and a half of living in India, my wife would sometimes listen to me speaking and burst into laughter, "Did you hear what you just said?" I was speaking Indian English. > >Being the worst guy in the band brought out the same behavior in me as a saxophonist, I would naturally just play like everyone else. What makes this phenomenon really unglamorous is that when I played in casinos and hole-in-the-wall bars with those not-so-good bands, I played like those guys. Also, like an alcoholic who slurs his speech even when he's not drunk, I'd find the bad habits of the bar bands carrying over to my non-bar-band nights. > >So, I learned from this that people can significantly improve or regress in skill, purely based on who they are performing with. And, prolonged experience with a group can have a lasting impact on one's ability to perform. > >The people around you affect your own performance. Choose your crowd wisely. > >Later, as I moved into the computer industry, I found that this learned habit of seeking out the best musicians came naturally to me as a programmer Perhaps unconsciously, I sought out the best IT people to work with. And, not surprisingly, the lesson holds true. Being the worst guy (or gal, of course) on the team has the same effect as being the worst guy in the band. You find that you're unexplainably smarter. You even speak and write more intelligently. Your code and designs get more elegant, and you find that you're able to solve hard problems with increasingly creative solutions. > >Let's go back to the first reason that I was able to blend into those bands better than I expected. I really wasn't as bad as I thought. In music, it's pretty easy to measure whether other musicians think you're good. If you're good, they invite you to play with them again. If you're not, they avoid you. It's a much more reliable measurement than just asking them what they think, because good musicians don't like playing with bad ones. Much to my surprise, I found that in many of these cases, I would get called by one or more of these superior musicians for additional work or to even start bands with them. > >Attempting to be the worst actually stops you from selling yourself short. You might belong in the A band but always put yourself in the B band, because you're afraid. Acknowledging outright that you're not the best wipes away the fear of being discovered for the not-best person you are. In reality, even when you try to be the worst, you won't actually be. Having said all that, I have to add that as Ecclesiastes/Kohelet (1:9) had said: there is nothing new under the sun (אֵין כָּל חָדָשׁ תַּחַת הַשָּׁמֶשׁ) (in the context of the above :), since in the Ethics of the Elders ([[Pirkei Avot 4:15|https://www.sefaria.org/Pirkei_Avot.4?lang=bi]], פרקי אבות, פרק ד, יח, written in the third century C.E.) they had said: > Be a tail to lions, rather than a head to foxes. > ( וֶהֱוֵי זָנָב לָאֲרָיוֹת, וְאַל תְּהִי רֹאשׁ לַשּׁוּעָלִים )
Video clip from the new Cosmos series ("[[Cosmos: A Spacetime Odyssey|http://channel.nationalgeographic.com/cosmos-a-spacetime-odyssey/]]" presented by Neil deGrasse Tyson) [[A Pale Blue Dot|https://www.youtube.com/watch?v=p86BPM1GV8M]] and [[Wikipedia|http://en.wikipedia.org/wiki/Pale_Blue_Dot]]:
!!!!Sagan's original text (from his book; also accompanying the video):
>From this distant vantage point, the Earth might not seem of any particular interest. But for us, it's different. Consider again that dot. That's here. That's home. That's us. On it everyone you love, everyone you know, everyone you ever heard of, every human being who ever was, lived out their lives. The aggregate of our joy and suffering, thousands of confident religions, ideologies, and economic doctrines, every hunter and forager, every hero and coward, every creator and destroyer of civilization, every king and peasant, every young couple in love, every mother and father, hopeful child, inventor and explorer, every teacher of morals, every corrupt politician, every "superstar," every "supreme leader," every saint and sinner in the history of our species lived there – on a mote of dust suspended in a sunbeam.
>The Earth is a very small stage in a vast cosmic arena. Think of the rivers of blood spilled by all those generals and emperors so that in glory and triumph they could become the momentary masters of a fraction of a dot. Think of the endless cruelties visited by the inhabitants of one corner of this pixel on the scarcely distinguishable inhabitants of some other corner. How frequent their misunderstandings, how eager they are to kill one another, how fervent their hatreds. Our posturings, our imagined self-importance, the delusion that we have some privileged position in the universe, are challenged by this point of pale light. Our planet is a lonely speck in the great enveloping cosmic dark. In our obscurity – in all this vastness – there is no hint that help will come from elsewhere to save us from ourselves.
>The Earth is the only world known, so far, to harbor life. There is nowhere else, at least in the near future, to which our species could migrate. Visit, yes. Settle, not yet. Like it or not, for the moment, the Earth is where we make our stand. It has been said that astronomy is a humbling and character-building experience. There is perhaps no better demonstration of the folly of human conceits than this distant image of our tiny world. To me, it underscores our responsibility to deal more kindly with one another and to preserve and cherish the pale blue dot, the only home we've ever known.
>>-- Carl Sagan, Pale Blue Dot: A Vision of the Human Future in Space, 1997 reprint, pp. xv–xvi
I would suggest that science is, at least in part, informed worship. My deeply held belief is that if a god of anything like the traditional sort exists, then our curiosity and intelligence are provided by such a God. We would be unappreciative of those gifts if we suppressed our passion to explore the universe and ourselves. On the other hand if such a traditional God does not exist, then our curiosity and our intelligence are the essential tools for managing our survival in an extremely dangerous time. In either case the enterprise of knowledge is consistent surely with science; it should be with religion, and it is essential for the welfare of the human species.
Alison Gopnik quotes David Hume ("Causality is the cement of the universe") in [ext[a paper on causality|resources/Gopnik - causality.pdf]], saying that causation is central to human knowledge and the human experience, but it is "tricky", and led the philosopher Bertrand Russel to declare that causality should be ruled out of philosophical discussion altogether "The law of causality, I believe, like much that passes muster among philosophers, is a relic of a bygone age, surviving, like the monarchy, only because it is erroneously supposed to do no harm". (Talk about a strong statement!)
(See also a [[thought-provoking lecture by Judea Pearl|On The Art and Science of Cause and Effect - Judea Pearl]] (who also quotes Russell in a similar context)).
Another [[interesting paper on constructivism, causal models, Bayesian learning mechanisms|Reconstructing constructivism: Causal models, Bayesian learning mechanisms and the theory theory]] by Gopnik.
This ''Cellular Automaton (CA)'' rule as [[described by Stephen Wolfram|http://mathworld.wolfram.com/Rule110.html]] This rule is a collection of state machines (on the 2D endless board, a-la [[Conway's Game Of Life|http://en.wikipedia.org/wiki/Conway%27s_Game_of_Life]]) producing intricate, non-predictable (but fully calculatable) patterns/behavior, which is neither completely stable nor completely chaotic. Rule 110 has been proven to be [[Turing complete|http://en.wikipedia.org/wiki/Turing_completeness]], that is, capable of [[universal computation|http://en.wikipedia.org/wiki/Universal_computation]]. The rule definition: <a href="./resources/rule_110_def.gif" target="new"><img src="./resources/rule_110_def.gif" width="50%" height="50%" /></a> A small sample output: <a href="./resources/rule_110_output.gif" target="new"><img src="./resources/rule_110_output.gif" width="50%" height="50%" /></a> It's interesting to read [[what Ray Kurzweil has to say|http://www.kurzweilai.net/reflections-on-stephen-wolfram-s-a-new-kind-of-science]] about Wolfram's statements on CA, complexity, and life: >Wolfram makes the following point repeatedly: Whenever a phenomenon is encountered that seems complex it is taken almost for granted that the phenomenon must be the result of some underlying mechanism that is itself complex. But my discovery that simple programs can produce great complexity makes it clear that this is not in fact correct. >I do find the behavior of Rule 110 rather delightful. However, I am not entirely surprised by the idea that simple mechanisms can produce results more complicated than their starting conditions. We've seen this phenomenon in fractals (i.e., repetitive application of a simple transformation rule on an image), chaos and complexity theory (i.e., the complex behavior derived from a large number of agents, each of which follows simple rules, an area of study that Wolfram himself has made major contributions to), and self-organizing systems (e.g., neural nets, Markov models), which start with simple networks but organize themselves to produce apparently intelligent behavior. At a different level, we see it in the human brain itself, which starts with only 12 million bytes of specification in the genome, yet ends up with a complexity that is millions of times greater than its initial specification.
In a [[New York Times article from 1984|http://www.nytimes.com/1984/06/10/magazine/solving-the-mathematical-riddle-of-chaos.html]], [[James Gleick|https://around.com/about/]] (of ~Time-Travel, Chaos, and other-fascinating-books fame) wrote about the (savant?) mathematician Mitchell Feigenbaum and other mathematicians tackling Chaos and how its understanding will affect our thinking ("Chaos [Theory] is asking very, very hard questions," says Joseph Ford, Regents Professor of the Georgia Institute of Technology. "It offers the possibility that the answers are going to severely modify our view of the universe.")
In the article Gleick covers^^1^^, almost in passing, one of the "hard questions", that of Free Will:
>The dripping faucet, for example. [Robert Shaw at the Institute for Advanced Study], a physicist who is another product of the Santa Cruz Collective, has been studying it for several years as a theoretical paradigm of chaos.
>[...] A slow drip can be quite regular, each drop a little bag of surface tension that breaks off when it reaches a certain size. But the size of the drop changes slightly depending on the speed of the flow and depending on whether there is a little rebound from the drop before. And that is enough to make the system nonlinear.
>
>"If you turn it up you can see a regime where the drops are still separate but the pitter-patter becomes irregular," Shaw says. "As it turns out, it's not a predictable pattern beyond a short period of time."
>[...] For some scientists, there is reason to pause when they explore systems as simple as a faucet and find that they are, as Shaw says, eternally creative.
To me, the description above ("eternally creative") hits the nail on the head. Doesn't it say (or at least imply) that we (humans) //interpret// some random behaviors as creativity? And isn't creativity one of the signs/features of Free Will (see below)?
>Practically speaking, it means that scientists have to think differently about the problems of nature. It changes their intuitions about what the answers can look like, and that changes the questions they ask. Chaos becomes a technique for doing science - but it also becomes a conceptual framework on which theoreticians can hang some of their most treasured suspicions about the workings of the universe.
>
So, here we go (with the reference in passing):
>To some physicists, chaos seems like a kind of answer to the problem of free will. The realization that the simplest, most deterministic equations can look just like random noise suggests - philosophically, at least - that the Calvinists' deterministic view of the world can be reconciled with the appearance of free will.
And Gleick moves on:
>To people like Ford, chaos is also something like a death knell for the probabilistic ideas of quantum mechanics. "Chaos makes it absolutely clear what the limits are," he says. Last year he gave a talk titled, after Einstein, "Does God Play Dice With the Universe?"
>
>"The answer is yes, of course," he says. "But they're loaded dice. And the main objective of physics now is to find out by what rules were they loaded and how can we use them to our own ends."
If I correctly understand the above, it says that while "probabilistic ideas in quantum mechanics" (and for example, concepts like "wave functions") say that there are probability distributions for describing behaviors of things, and as such, there is, at least in theory, a "probability smear" from minus-infinity to plus-infinity on these phenomena.
But, Chaos Theory is "more committal" in the sense that it puts limits, structures, patterns around these same phenomena, basically "rejecting" the infinite "smear".
>To some artificial intelligence specialists at the Institute for Advanced Study and at Los Alamos, chaos suggests a means of linking the simple behavior of neurons to the unpredictable behavior of brains. And to Feigenbaum himself, it is at least a glimpse of a way to link the analytic achievements of his profession to his intuitions about the world.
----
^^1^^ - The bulk of Gleick's article is not about Free Will, but about the potential of Chaos Theory (and Mitchell Feigenbaum and others) to change our thinking^^2^^, and in this respect, it is a different attempt to "explain away" some of the (so-far? forever?) unexplainable/incomprehensible aspects of Quantum Mechanics, [[something that Edwin Jaynes is also trying to do|Clearing up physical mysteries with probability]].
^^2^^ - or as Douglas Hofstadter wrote in [[Metamagical Themas: Questing for the Essence of Mind and Pattern|http://avalonlibrary.net/ebooks/Douglas%20Hofstadter%20-%20Metamagical%20Themas.pdf]]:
>It turns out that an eerie type of chaos can lurk just behind a facade of order - and yet, deep inside the chaos lurks an even eerier type of order.
A nice [ext[example of human-centric, transparent, performance-enhancing technology|resources/Natural-Born Cyborgs - ch2.docx]]
This example talks about a scenario where someone on the streets asks you for the time, and you, having a ("cheap but reliable") wristwatch tell them what the time is. Clark is arguing that we, our minds, selves, etc., extend beyond the boundaries of our skull and skin. We naturally extend our intelligence:
>When we answer that we know the time, all we mean is that we have the information readily at hand. And to be sure, several cultural variants of the request exist. My wife, a native Spanish speaker, might ask me Tienes hora? literally, Have you got the time? with the emphasis on possession rather than knowledge. All this notwithstanding, I think the ease with which we accept talk of the watch-bearer as one who actually knows rather than one who can easily find out the time is suggestive. For the line between that which is easily and readily accessible and that which should be counted as part of the knowledge base of an active intelligent system is slim and unstable indeed. It is so slim and unstable, in fact, that it sometimes makes both social and scientific sense to think of your individual knowledge as quite simply whatever body of information and understanding is at your fingertips; whatever body of information and understanding is right there, cheaply and easily available, as and when needed.
So,
>you are telling the literal truth when you answer yes to the innocent-sounding question Do you know the time? For you do know the time. It is just that the you that knows the time is no longer the bare biological organism but the hybrid biotechnological system that now includes the wristwatch as a proper part.
and concludes:
>We can, in any event, take away two somewhat less contentious lessons from our discussion of modern timekeeping. The first is that transparent (nonopaque, human-centered) technology is by no means a new invention. It is with us already in a wide variety of old technologies, including pen, paper, books, watches, written words, numerical notations, and the multitude of almost-invisible props and aids that scaffold and empower our daily thought and action. The second is that the passage to transparency often involves a delicate and temporally extended process of co-evolution. Certainly, the technology must change in order to become increasingly easy to use, access, and purchase; but this is only half the story because at the same time, elements of culture, education, and society must change also. In the case at hand, people had to learn to value time discipline as opposed to mere time obedience, and this transition itself, Landes tells us, took over a hundred years to fully accomplish.
Clark talks about the nature of tools and technologies that really/significantly enhance human capabilities: >What if we instead allowed them to define brand new niches for genuine action and intervention? The idea would be to allow the technologies to provide for the kinds of interactions and interventions for which they are best suited, rather than to force them to (badly) replicate our original forms of action and experience. About written language (and ''literacy'') vs. face-to-face conversation >After all, our single most fantastically successful piece of transparent cognitive technology written language is not simply a poor cousin of face-to-face vocal exchange. Instead, it provides a new medium for both the exchange of ideas and (more importantly) for the active construction of thoughts. We celebrate it for its special virtues, not as an impersonal, low-bandwidth, less rapidly responsive stand-in for face-to-face exchange. >This point is nicely made in a short piece by two Bellcore researchers, Jim Hollan and Scott Stormetta. The piece is called Beyond Being There and kicks off with an analogy. A human with a broken leg may use a crutch, but as soon as she is well, the crutch is abandoned. Shoes, however (running shoes especially), enhance performance even while we are well. Too much telecommunications research, they argue, is geared to building crutches rather than shoes. Both are tools. We may become as accustomed to the crutches as the shoes, but crutches are designed to remedy a perceived defect and shoes to provide new functionality. Maybe new technologies should aspire to the latter. As they put it: >>[much] telecommunications research seems to work under the implicit assumption that there is a natural and perfect state being there and that our state is in some sense broken when we are not physically proximate. . . . In our view, there are a number of problems with this approach. Nor only does it orient us towards the construction of crutch-like telecommunications tools but it also implicitly commits us to a general research direction of attempting to imitate one medium of communication with another. >Consider e-mail. E-mail is often used even when the recipient is sitting in the office next door. I do this all the time. My neighbor is a university colleague and for certain delicate, slow conversations, we much prefer a slow, asynchronous e-mail exchange. But e-mail is nothing like face-to-face interaction, and therein lies its virtues. It provides complementary functionality, allowing people informally and rapidly to interact, while preserving an inspectable and revisitable trace. It does this without requiring us both to be free at the same time. Cell phone text messaging has related virtues. The tools that really take off, Hollan and Stormetta thus argue, are those that people prefer to use [for certain purposes] even when they have the option of interacting in physical proximity . . . tools that go beyond being there.
<<list-links "[tag{!!title}]">>
In [[an interesting talk|http://www.johnseelybrown.com/WorkingLearningLeading.pdf]] at the 2016 AACSB International Deans Conference, John Seely Brown (former Chief Scientist of Xerox Corporation and former director of the Xerox Palo Alto Research Center (PARC)) talked about (among other things :) the characteristics of good leaders, but I found them very relevant and applicable to teachers. (there is overlap with [[another talk he gave at Stanford|Sense-making and learning in the new 21st century environment]] about sense-making in the 21st century) * In this new era, leadership (and educating/teaching) is more akin to gardening than to chess playing ** I think that it is useful to compare/think about what [[Joe Kirby wrote in his blog|https://pragmaticreform.wordpress.com/2013/05/11/great-teaching/]] about exceptional teachers: >>A great analogy here is that in their subjects, most teachers play draughts [checkers]; great teachers play chess. Deep strategic subject knowledge of how the movements of the pieces combine is crucial to effective instruction. *** The way I think of the seeming difference between the two statements (which I do believe are both true!) is that each one is referring to a different aspect of good teachers/teaching. The gardener metaphor, I think, relates to the nurturing of the student, the relationship, the needs and interests (of the "plants"). Whereas, I think that the chess metaphor relates to the treating of the material/domain to be taught (the concepts, principles, skills, priorities, and relationships between them (the "pieces")) * authenticity and integrity are vital >How do we begin to develop these types of leaders? It starts with authenticity. Like a whitewater kayaker navigating the rapids, interpreting the ripples and understanding what they reveal about what lies beneath the surface, we must live in an ongoing conversation with the flows and changes happening around us. This requires living totally in the moment, experiencing the immediate at-hand circumstances of actions and quickly analyzing information using all senses. When a strong rapid pushes the kayak off balance, or even flips it over, what keeps a kayaker afloat or what helps him roll back to the surface is his center of gravity. It is the axis of balance that gives him the confidence to take on the whitewater and increase his levels of risk-taking. In this metaphor, the line of balance is analogous to authenticity and integrity. Authenticity is simply the capacity to know yourself, your core strengths, weaknesses, values and motivations, and to work from and for them. In a radically contingent whitewater world, decisions and actions critically need an authentic place to work from. That is your base of operation. * in an era of complexity and wicked problems, we need to move from problem solving with an engineering approach to working ecosystemically. Teachers need to learn to do that, and they have to teach students to do that!
From the book //On Intelligence// (published in 2004) by Jeff Hawkins (pg. 25): I had formed an opinion that three things were essential to understanding the brain. My ''first criterion'' was @@the inclusion of time@@ in brain function. Real brains process rapidly changing streams of information. There is nothing static about the flow of information into and out of the brain. The ''second criterion'' was @@the importance of feedback@@. Neuroanatomists have known for a long time that the brain is saturated with feedback connections. For example, in the circuit between the neocortex and a lower structure called the thalamus, connections going backward (toward the input) exceed the connections going forward by almost a factor of ten! That is, for every fiber feeding information forward into the neocortex, there are ten fibers feeding information back toward the senses. Feedback dominates most connections throughout the neocortex as well. No one understood the precise role of this feedback, but it was clear from published research that it existed everywhere. I figured it must be important. The ''third criterion'' was that any theory or model of the brain should account for @@the physical architecture of the brain@@. The neocortex is not a simple structure. As we will see later, it is organized as a repeating hierarchy. And Jeff Hawkins' conclusion: Any neural network that didn't acknowledge this structure was certainly not going to work like a brain.
<<list-links "[tag{!!title}]">>
[[Chris Crawford|http://en.wikipedia.org/wiki/Chris_Crawford_%28game_designer%29]]
a game designer
<<list-links "[tag{!!title}]">>
The [[Edgie, Christopher Langton|https://www.edge.org/memberbio/christopher_g_langton]] (of [[Langton's Ant|https://en.wikipedia.org/wiki/Langton%27s_ant]] fame), is [[talking about Dynamical Patterns|https://www.edge.org/conversation/christopher_g_langton-chapter-21-a-dynamical-pattern]], where he describes some of the advances made in Artificial Life, Artifical Intelligence, Genetic Algorithms and simulations. In the conversation he brings up something echoing the situation we had before computers were able to beat human chess grand masters: >It's going to be hard for people to accept the idea that machines can be as alive as people, and that there's nothing special about our life that's not achievable by any other kind of stuff out there, if that stuff is put together in the right way. It's going to be as hard for people to accept that as it was for Galileo's contemporaries to accept the fact that Earth was not at the center of the universe. Vitalism is a philosophical perspective that assumes that life cannot be reduced to the mere operation of a machine, but, as the British philosopher and scientist [[C.H. Waddington|https://en.wikipedia.org/wiki/C._H._Waddington]] has pointed out, this assumes that we know what a machine is and what it's capable of doing. He brings up a detail which may be ignored by many, namely, that our points of view, opinions, and definitions are not necessarily fixed (nor, as he points out, clear!). The frontier (or separating line) of the terms "machine", "intelligence" is moving. Similar to what had happened with chess, where people initially had predicted that computers will never be able to play "good chess", let alone beat humans (since it had been considered one of the top creative (in addition to analytical) human activities/abilities), this can (will?) happen with other "uniquely human" abilities, achievements, characteristics. It's possible that machines (in the evolving, constantly expanding sense) will accomplish these "pinnacles" (also in the evolving sense) in radically different ways from humans (similar to [[how chess machines use totally different techniques/approaches|On human thinking vs. machine thinking in chess]], which nonetheless, are successful), and this unknown (and at this point, or at any point, unknowable, really) quality is what may excite some, and scare others. Or as Langton points out: >It's easy to descend into fantasy at this point, because we don't know what the possible outcome of producing "genuine" artificial life will be. If we create robots that can survive on their own, can refine their own materials to construct offspring, and can do so in such a way as to produce variants that give rise to evolutionary lineages, we'll have no way of predicting their future or the interactions between their descendants and our own. There are quite a few issues we need to think about and address before we initiate such a process. And illustrates: >A reporter once asked me how I would feel about my children living in an era in which there was a lot of artificial life. I answered, "Which children are you referring to? My biological children, or the artifactual children of my mind?" — to use [[Hans Moravec|https://www.edge.org/memberbio/hans_moravec]]'s phrase. They would both be my children, in a sense. Langton then brings up another "chilling" scenario/thought (chilling can be either in the sense of scary, or, as Langton points out, "contributing to objectivity" and "cool/rational thinking"): >Another set of philosophical issues raised in the pursuit of artificial life centers on questions of the nature of our own existence, of our own reality and the reality of the universe we live in. After working for a long time creating these artificial universes, wondering about getting life going in them, and wondering if such life would ever wonder about its own existence and origins, I find myself looking over my shoulder and wondering if there isn't another level on top of ours, with something wondering about me in the same way. It's a spooky feeling to be caught in the middle of such an ontological recursion. This is [[Edward Fredkin|https://en.wikipedia.org/wiki/Edward_Fredkin]]'s view: the universe as we know it is an artifact in a computer in a more "real" universe. This is a very nice notion, if only for the perspective to be gained from it as a thought experiment — as a way to enhance one's objectivity with respect to the reality one's embedded in.
<<list-links "[tag[citizen-schools-item]]">>
H. G. Wells: Civilization is in a race between education and catastrophe. [[Alan Kay|https://en.wikipedia.org/wiki/Alan_Kay]] (a "[[CS Sage|https://en.wikipedia.org/wiki/List_of_computer_scientists]]"), at OOPSLA 1997, gave an [[insightful talk|https://www.youtube.com/watch?v=oKg1hTOQXoY]] titled [[The Real Computer Revolution Has Not Happened Yet]] ([[the 2007 transcript|http://www.vpri.org/pdf/m2007007a_revolution.pdf]]), modifies it and explains: Perhaps “education” is too vague a term here. I would replace it with “a race between education of outlook and catastrophe” because it is not knowledge per se that makes the biggest difference, but outlook or point of view which provides the context in which rational thinking actually matches up with the real world in the service of humanity.
[[“Claiming an Education” is a commencement speech|http://isites.harvard.edu/fs/docs/icb.topic469725.files/Rich-Claiming%20an%20Education-1.pdf]] by Adrienne Rich, delivered at the convocation of Douglass College, 1977. Rich opens by describing what the relationship between teacher and student ought to be (vs. what it often is :( >If university education means anything beyond the processing of human beings into expected roles, through credit hours, tests, and grades (and I believe that in a women's college especially it might mean much more), it implies an ethical and intellectual contract between teacher and student. This contract must remain intuitive, dynamic, unwritten; but we must turn to it again and again if learning is to be reclaimed from the depersonalizing and cheapening pressures of the present-day academic scene. She urges students to have the appropriate perspective about education, something every (life-long) learner should keep in mind: >you cannot afford to think of being here to receive an education: you will do much better to think of being here to claim one. >One of the dictionary definitions of the verb "to claim" is: to take as the rightful owner; to assert in the face of possible contradiction. >"To receive" is to come into possession of: to act as receptacle or container for; to accept as authoritative or true. >The difference is that between acting and being acted-upon, and for women it can literally mean the difference between life and death. Rich, who was a feminist, makes some observations about the (white) male-dominated bias which pervades the entire higher education curriculum, but I will not focus on this aspect (and you are welcome to read [[the whole speech|http://isites.harvard.edu/fs/docs/icb.topic469725.files/Rich-Claiming%20an%20Education-1.pdf]]). She, too, wants to focus on a higher level issue: >But my talk is not really about women's studies, much as I believe in their scholarly, scientific, and human necessity. While I think that any Douglass student has everything to gain by investigating and enrolling in women's studies courses, I want to suggest that there is a more essential experience that you owe yourselves, one which courses in women's studies can greatly enrich, but which finally depends on you in all your interactions with yourself and your world. This is the experience of taking responsibility toward yourselves. She obviously speaks to and about women, but this applies to all of us: * Responsibility to yourself means refusing to let others do your thinking, talking, and naming for you; it means learning to respect and use your own brains and instincts; hence, grappling with hard work. * It means insisting that those to whom you give your friendship and love are able to respect your mind. It means being able to say, with Charlotte Bronte's Jane Eyre: "I have an inward treasure born with me, which can keep me alive if all the extraneous delights should be withheld or offered only at a price I cannot afford to give." * Responsibility to yourself means that you don't fall for shallow and easy solutions -- predigested books and ideas, weekend encounters guaranteed to change your life, taking "gut" courses instead of ones you know will challenge you, bluffing at school and life instead of doing solid work, marrying early as an escape from real decisions, getting pregnant as an evasion of already existing problems. * It means that you refuse to sell your talents and aspirations short, simply to avoid conflict and confrontation. * And this, in turn, means resisting the forces in society which say that women should be nice, play safe, have low professional expectations, drown in love and forget about work, live through others, and stay in the places assigned to us. * It means that we insist on a life of meaningful work, insist that work be as meaningful as love and friendship in our lives. * It means, therefore, the courage to be "different"; not to be continuously available to others when we need time for ourselves and our work; to be able to demand of others -- parents, friends, roommates, teachers, lovers, husbands, children -- that they respect our sense of purpose and our integrity as persons. And she rightly observes: > The difference between a life lived actively, and a life of passive drifting and dispersal of energies, is an immense difference. Once we begin to feel committed to our lives, responsible to ourselves, we can never again be satisfied with the old, passive way. Rich has some observations about and advice to teachers: * Too often, all of us [teachers] fail to teach the most important thing, which is that clear thinking, active discussion, and excellent writing are all necessary for intellectual freedom, and that these require hard work. * [We, teachers should not] resign ourselves to low expectations for our students before we have given them half a chance to become more thoughtful, expressive human beings. * [And she quotes] Elizabeth Barrett Browning, a poet, a thinking woman, and a feminist, who wrote in 1845 of her impatience with studies which cultivate a "passive recipiency" in the mind, and asserted that "women want to be made to think actively: their apprehension is quicker than that of men [...] She is coming back to the contract between learner and teacher (and I will change the text to reflect learners in general, and not just women (which is the case in the original speech), since I believe she makes strong and valid cases which apply to all): * I have said that the contract on the student's part involves that you demand to be taken seriously so that you can also go on taking yourself seriously. * This means seeking out criticism, recognizing that the most affirming thing anyone can do for you is demand that you push yourself further, show you the range of what you can do. * It means rejecting attitudes of "take-it-easy," "why-be-so-serious," "why-worry-you'll-probably-get-married-anyway." * It means assuming your share of responsibility for what happens in the classroom, because that affects the quality of your daily life here. * It means that the student sees herself engaged with her teachers in active, ongoing struggle for a real education. And she concludes: >But for [the learners] to do this, [their] teachers must be committed to the belief that [learners'] minds and experience are intrinsically valuable and indispensable to any civilization worthy the name. > >The contract is really a pledge of mutual seriousness about learners, about language, ideas, method, and values. It is our shared commitment toward a world in which the inborn potentialities of so many [learners'] minds will not longer be wasted, raveled-away, paralyzed, or denied.
In an illuminating and forceful article^^1^^ titled [[CLEARING UP MYSTERIES - THE ORIGINAL GOAL|http://worrydream.com/refs/Jaynes%20-%20Clearing%20up%20Mysteries.pdf]], [[Edwin T. Jaynes|https://en.wikipedia.org/wiki/Edwin_Thompson_Jaynes]] argues that a clear understanding and application of statistics, specifically Conditional Probability (Bayes), can clear up very vexing paradoxes in physics, such as diffusion of a solution of sugar in water, the ~Einstein-Podolsky-Rosen (EPR) "spooky action at a distance" (or Einstein's expression in German: spukhafte Fernwirkung), and the applicability/violation of the second law of thermodynamics in biology.
Or in Jaynes's words:
>The first example is a simple exercise in kinetic theory that has puzzled generations of physics students: how does one calculate a diffusion coefficient and not get zero? The second concerns the currently interesting ~Einstein-Podolsky-Rosen paradox and Bell inequality mysteries in quantum theory: do physical influences travel faster than light? The third reexamines the old mystery about whether thermodynamics applies to biology: does the high efficiency of our muscles violate the second law?
Jaynes emphasizes the point that prior knowledge directly impacts our predictions about the future, in the sense of conditional probabilities (Bayes):
>The idea that probabilities can be used to represent our own information is still foreign to "orthodox" teaching [...]. Orthodoxy does not provide any technical means for taking prior information into account; yet that prior information is often highly cogent, and sound reasoning requires that it be taken into account. In other fields this is considered a platitude; what would you think of a physician who looked only at your present symptoms, and refused to take note of your medical history?
Another critical distinction he makes is between what happens in the "real world" (whatever that may be) and what we know (or can say at this point) about what we think/know is happening in the "real world":
>To appreciate the distinction between physical prediction and inference it is essential to recognize that propositions at two different levels are involved. In physical prediction we are trying to describe the real world; in inference we are describing only our state of knowledge about the world. A philosopher would say that physical prediction operates at the ontological level, inference at the epistemological level. Failure to see the distinction between reality and our knowledge of reality puts us on the Royal Road to Confusion; this usually takes the form of the Mind Projection Fallacy, discussed below.
>The confusion proceeds to the following terminal phase: a Bayesian calculation like the above one operates on the epistemological level and gives us only the best predictions that can be made from the information that was used in the calculation. But it is always possible that in the real world there are extra controlling factors of which we were unaware; so our predictions may be wrong. Then one who confuses inference with physical prediction would reject the calculation and the method; but in so doing he would miss the point entirely.
Clarifying the difference between the epistemological and ontological levels:
>For one who understands the difference between the epistemological and ontological levels, a wrong prediction is not disconcerting; quite the opposite. For how else could we have learned about those unknown factors? It is only when our epistemological predictions fail that we learn new things about the real world; those are just the cases where probability theory is performing its most valuable function. Therefore, to reject a Bayesian calculation because it has given us an incorrect prediction is like disconnecting a fire alarm because that annoying bell keeps ringing. Probability theory is trying to tell us something important, and it behooves us to listen.
!!!On the MIND PROJECTION FALLACY:
>It is very difficult to get this point across to those who think that in doing probability calculations their equations are describing the real world. But that is claiming something that one could never know to be true; we call it the Mind Projection Fallacy. The analogy is to a movie projector, whereby things that exist only as marks on a tiny strip of film appear to be real objects moving across a large screen. Similarly, we are all under an ego{driven temptation to project our private thoughts out onto the real world, by supposing that the creations of one's own imagination are real properties of Nature, or that one's own ignorance signifies some kind of indecision on the part of Nature.
And the "double benefit" of using probability's power:
>In our more humble view of things, the probability distributions that we use for inference do not describe any property of the world, only a certain state of information about the world. This is not just a philosophical position; it gives us important technical advantages because of the more flexible way we can then use probability theory. In addition to giving us the means to use prior information, it makes an analytical apparatus available for such things as eliminating nuisance parameters, at which orthodox methods are helpless. This is a major reason for the greater computational efficiency of the [[Jeffreys methods in data analysis|https://arxiv.org/pdf/0804.3173.pdf]].
!!!On EPR ("spooky action at a distance", or in German: spukhafte Fernwirkung)
Jaynes summarizes EPR as follows:
>The ~Einstein-Podolsky-Rosen (EPR) article of 1935 is Einstein's major effort to explain his objection to the completeness claim by an example that he thought was so forceful that nobody could miss the point. Two systems, S1 and S2, that were in interaction in the past are now separated, but they remain jointly in a pure state. Then EPR showed that according to QM [Quantum Mechanics] an experimenter can measure a quantity q1 in S1, whereupon he can predict with certainty the value of q2 in S2. But he can equally well decide to measure a quantity p1 that does not commute with q1; whereupon he can predict with certainty the value of p2 in S2. The systems can be so far apart that no light signal could have traveled between them in the time interval between the S1 and S2 measurements. Therefore, by means that could exert no causal inuence on S2 according to relativity theory, one can predict with certainty either of two noncommuting quantities, q2 and p2. EPR concluded that both q2 and p2 must have had existence as definite physical quantities before the measurements; but since no QM state vector is capable of representing this, the state vector cannot be the whole story.
Jaynes sums up Enstein's and Bohr's positions on Quantum Mechanics (QM):
>Put most briefly, Einstein held that the QM formalism is incomplete and that it is the job of theoretical physics to supply the missing parts; Bohr claimed that there are no missing parts. To most, their positions seemed diametrically opposed; however, if we can understand better what Bohr was trying to say, it is possible to reconcile their positions and believe them both. Each had an important truth to tell us.
This boils down to ontology vs. epistemology (see also [[Different worldviews of Physics Greats]]):
>But Bohr and Einstein could never understand^^2^^ each other because they were thinking on different levels. When Einstein says QM is incomplete, he means it in the ontological sense; when Bohr says QM is complete, he means it in the epistemological sense. Recognizing this, their statements are no longer contradictory. Indeed, Bohr's vague, puzzling sentences -- always groping for the right word, never finding it -- emerge from the fog and we see their underlying sense, if we keep in mind that Bohr's thinking is never on the ontological level traditional in physics. Always he is discussing not Nature, but our information about Nature. But physics did not have the vocabulary for expressing ideas on that level, hence the groping.
And on limitations on human predictions vs. human measurements:
>Needless to say, we consider all of Einstein's reasoning and conclusions correct on his level; but on the other hand we think that Bohr was equally correct on his level, in saying that the act of measurement might perturb the system being measured, placing a limitation on the information we can acquire and therefore on the predictions we are able to make. There is nothing that one could object to in this conjecture, although the burden of proof is on the person who makes it. But we part company from Bohr when this metamorphoses without explanation into a claim that the limitation on the predictions of the present QM formalism are also -- in exact, minute detail -- limitations on the measurements that can be made in the laboratory!
>[...]
>We believe that to achieve a rational picture of the world it is necessary to set up another clear division of labour within theoretical physics; it is the job of the laws of physics to describe physical causation at the level of ontology, and the job of probability theory to describe human inferences at the level of epistemology. The Copenhagen theory scrambles these very different functions into a nasty omelette in which the distinction between reality and our knowledge of reality is lost.
>Although we agree with Bohr that in different circumstances (different states of knowledge) different quantities are predictable, in our view this does not cause the concepts themselves to fade in and out; valid concepts are not mutually incompatible. Therefore, to express precisely the effect of disturbance by measurement, on our information and our ability to predict, is not a philosophical problem calling for complementarity; it is a technical problem calling for probability theory as expounded by Jeffreys, and information theory.
Jaynes agrees with Einstein and claims the same dissatisfaction with QM, but he does not claim that Bohr was wrong; they were merely talking at different levels:
>To understand this, we must keep in mind that Einstein's thinking is always on the ontological level; the purpose of the EPR argument was to show that the QM state vector cannot be a representation of the \real physical situation" of a system. Bohr had never claimed that it was, although his strange way of expressing himself often led others to think that he was claiming this.
>From his reply to EPR, we find that Bohr's position was like this: \You may decide, of your own free will, which experiment to do. If you do experiment E1 you will get result R1. If you do E2 you will get R2. Since it is fundamentally impossible to do both on the same system, and the present theory correctly predicts the results of either, how can you say that the theory is incomplete? What more can one ask of a theory?"
At this point Jaynes gives an illuminating example from probability:
!!!BERNOULLI'S URN REVISITED
```
Define the propositions:
I == "Our urn contains N balls, identical in every respect except that M of them are red, the
remaining N - M white. We have no information about the location of particular balls in
the urn. They are drawn out blindfolded without replacement."
Ri == Red on the i'th draw, i = 1, 2, ..."
Successive draws from the urn are a microcosm of the EPR experiment. For the first draw, given
only the prior information I , we have
P(R1 | I ) = M / N
Now if we know that red was found on the first draw, then that changes the contents of the urn for
the second:
P(R2 |R1, I )=(M - 1) / (N - 1)
and this conditional probability expresses the causal influence of the first draw on the second.
But suppose we are told only that red was drawn on the second draw; what is now our probability
for red on the first draw? Whatever happens on the second draw cannot exert any physical influence
on the condition of the urn at the first draw; so presumably one who believes with Bell that a
conditional probability expresses a physical causal influence, would say that P(R1 | R2, I ) = P(R1 | I ).
But this is patently wrong; probability theory requires that
P(R1 | R2, I ) = P(R2 | R1, I ) : eq. 18
This is particularly obvious in the case M = 1; for if we know that the one red ball was taken in
the second draw, then it is certain that it could not have been taken in the first.
In (eq. 18) the probability on the right expresses a physical causation, that on the left only an
inference. Nevertheless, the probabilities are necessarily equal because, although a later draw
cannot physically affect conditions at an earlier one, information about the result of the second
draw has precisely the same effect on our state of know ledge about what could have been taken in
the first draw, as if their order were reversed.
Eq. (18) is only a special case of a much more general result. The probability of drawing any
sequence of red and white balls (the hypergeometric distribution) depends only on the number of
red and white balls, not on the order in which they appear; i.e., it is an exchangeable distribution.
From this it follows by a simple calculation that for all i and j,
P(Ri | I ) = P(Rj | I ) = M / N
That is, just as in QM, merely knowing that other draws have been made does not change our
prediction for any specified draw, although it changes the hypothesis space in which the prediction
is made; before there is a change in the actual prediction it is necessary to know also the results of
other draws. But the joint probability is by the product rule,
P(Ri, Rj | I ) = P(Ri | Rj , I ) P(Rj | I ) = P(Rj | Ri, I ) P(Ri | I )
and so we have for all i and j,
P (Ri | Rj , I ) = P(Rj | Ri, I )
and again a conditional probability which expresses only an inference is necessarily equal to one that
expresses a physical causation. This would be true not only for the hypergeometric distribution,
but for any exchangeable distribution. We see from this how far Karl Popper would have got with
his \propensity" theory of probability, had he tried to apply it to a few simple problems.
```
>It might be thought that this phenomenon is a peculiarity of probability theory. On the contrary, it remains true even in pure deductive logic; for if A implies B, then not-B implies not-A.
>But if we tried to interpret "A implies B" as meaning "A is the physical cause of B", we could hardly accept that "not-B is the physical cause of not-A". Because of this lack of contraposition, we cannot in general interpret logical implication as physical causation, any more than we can conditional probability. Elementary facts like this are well understood in economics (Simon & Rescher, 1966; Zellner, 1984); it is high time that they were recognized in theoretical physics.
----
^^1^^ [[Local copy|resources/Jaynes - Clearing up Mysteries.pdf]]
^^2^^ - regarding understanding among "Physics Greats": there is this anecdote about [[Sir Arthur Eddington|https://en.wikipedia.org/wiki/Arthur_Eddington]], who when asked if only three people in the world understood general relativity replied, “Who is the third?”
In his excellent, practical book, Goodliffe shares many relevant, time-proven, and insightful experiences, based on years of writing industrial strength code in "the factory" (commercial application development).
!!!On Defensive Programming
You may not want to adopt this attitude/mindset in all aspects of your life, but in programming it would make sense to take the following to heart:
> We have to distrust each other. It's our only defense against betrayal. - ''Tennessee Williams''
And as it relates to writing robust, "good code":
* There is a big difference between "working code", "correct code", and "good code":
** "working code" works most of the time, given certain/usual/expected inputs/data
** "correct code" works and won't crash and produce correct/expected results for all possible/expected/unexpected inputs.
*** However, not all "correct code" is "good code". The logic may be hard to follow, and it may be hard/expensive/impossible to maintain and evolve.
** "good code" is obviously "correct code", but it is also robust, efficient enough, practical to maintain and evolve.
* Writing defensive code means you should assume nothing (or assume the worst) about how your code will be run (the environment, calls/usage, inputs/data, etc.)
** Defensive programming is careful, guarded coding, designed for reliability, so that every component protects itself as much as possible.
** As Goodliffe says: it's a big, bad world out there. And while you can't create absolutely foolproof code, (there is always a fool^^1^^ that will succeed in breaking your code...), you should try very hard and be smart and careful about your coding.
** Employ a good coding style (for clarity, readability, debugging, maintenance). Like [[good writing style|Why writing style matters]], good coding style matters.
** Come up with a thoughtful, clear, sound design and structure
** Don't code in a hurry ("more haste, less speed").
** Trust no one. Problems may come from genuine users providing bogus inputs, malicious users trying to fail your program, the operating environment not working as you expect, external libraries behaving unexpectedly.
*** Absolutely anyone - including yourself - can introduce flaws and errors into your program.
** Write code for clarity, not brevity. Whenever you can choose between concise but potentially confusing code, and clear but potentially tedious code, use code that reads well, even if it is less elegant. Simplicity and straight-forwardness is a virtue.
** Protect code that should not be tinkered with from the outside. Keep code protected, internal, local. Keep the scope as tight as possible.
** Design and use safe data structures. Or failing that, use dangerous data structures safely.
** Check every return value. Inspect and deal with all error codes and return values.
** Handle system/environment resources (such as memory, CPU cycles, co-processors) carefully and respectfully. Manage them well.
** Initialize all variables at their point of declaration.
** Declare variables as late as possible. This will help you manage a tight scope, make the use cleared to a reader (and your self). This way, you will avoid having to hunt around for variables all over your code.
** Don't reuse temporary variables in multiple places. Create new variables each time, in each new context.
** Use standard language facilities, libraries, etc., and clearly define which version(s) you are using.
!!! On Source Code Layout and Presentation
As Goodliffe writes:
* Code style has been, is, and will continue to be the subject of holy wars, among programmers - professional, amateur, and student - where, unfortunately, intense disagreements degrade into mere name-calling ...
** Engaging in holy wars is unproductive and a waste of time; there are far more important things to focus our attention to.
** Unfortunately holy wars can go beyond code and style, and extend to editors, compilers, methodologies, the One True Language, and beyond.
** Holy wars: Just Say No. Don't get involved. Just walk away.
* Why do people get so worked up about this?
** Presentation dramatically affects the readability of code- no one wants to work with code that isn't easy to read.
** Presentation is also a very subjective and personal thing ... Familiarity breeds comfort and an alien style puts you on edge.
** Programmers are passionate about code, so presentation stirs deep emotions.
* Keep in mind the //real// audience for your source code: other programmers (and possibly, your future self). Write for their benefit.
* Good presentation is
** consistent (indentation, parentheses, braces, brackets, etc.)
** conventional (it make sense to adopt one of the major/popular/adopted styles rather than invent your own)
** concise (clear easy-to-understand logic, structure, conditions, constraints, etc.)
!!!On Naming Things (Giving Meaningful Things Meaningful Names)
As programmers we have control of the things we create in code, like variables, functions, objects, classes, files, types, etc.
* we should name them so they clearly tell the thing's identity and behavior.
* An object's name should describe it clearly ("transparent" naming :)
* The key to good naming is a good understanding of the thing you name. If you find it hard to name something, ask yourself if you really understand it, or why it exists
* A good name should be:
** descriptive (reflecting it's identity/purpose/role and behavior)
** technically correct (valid in that language and following it's rules)
** idiomatic (following the language's conventions)
** appropriate, taking the following into account:
*** length (favor clarity over brevity)
*** tone (don't use jokey/cutesy names)
* when naming, avoid giving names that are:
** cryptic
** too verbose
** ambiguous or vague
** too cute
!!! On Documenting Code
* The problems with documenting code (both inside and outside of the code) are:
** It is extra work, both writing it and reading it
** the documentation needs to be kept in sync with the code
** documents, like code, are hard to manage (version control, etc.)
** important things can be overlooked/ignored/not-found in external (not inside the code) documentation
* Self-documenting code is ''code'' that is written to be read. By humans. Easily. (and don't worry; the compiler will cope/forgive :)
* Good self-documenting code follows these guidelines:
** write simple code with good/clear stype/presentation
** make the "normal" execution path through the code obvious (as opposed to error handling, obscure/rare "else" cases, etc.)
** choose meaningful name (see Naming above)
** decompose into atomic/small functions
** name constants (avoid "magic numbers")
** emphasize important code
*** order declarations in a file/class helpfully - important information first, followed by private/detailed information later
*** group together related information
*** provide a file header, which includes a description of the content, it's overall purpose, etc.
** handle errors appropriately
** write meaningful comments. Only add comments if you can't improve the clarity of your code in any other way
!!! On Writing Code Comments
> Let's not overstate the case - there are things far more important to get right than comments. When you've written truly good code your comments are the //icing on the cake//, delicately placed to add aesthetics and value, rather than liberally slapped on to cover up all the cracks and blemishes.
Goodliffe continues:
* learn to write ''enough'' comments, and no more. Favor quality, not quantity.
* spend your time writing code that doesn't need to be propped up by tons of comments.
* you should think carefully about what you write, since as Horace said:
> Of writing well the source and fountainhead is wise thinking.
* in your comments, __explain why, not how__. Anyone can see the 'how' by reading the code (which you have written clearly and effectively, haven't you? :). In your comments focus on intent. Good comments (the 'why') change less often, even if the code itself (the 'how') changes.
* if you find yourself writing dense and long/complex comments, stop to think whether you can simplify/clarify you code, so as to avoid lengthy/complicated commenting.
* make your comments as useful as possible:
** comments should "live in the present". Don't document how/why things were done in the past. Revision control can tell that story.
** document/comment on the unexpected results/cases/behavior of your code
** tell the truth. Comments should be up-to-date with the code, and not misrepresent what's going on
** are worthwhile. Avoid witty, cryptic comments; don't use expletives. Don't write comments that may embarrass you later.
** are readable, clear, unambiguous, specific
* A comment on comment aesthetics
** use a consistent commenting style
** block comments (multi-line), should be appropriately/well indented
** line comments should fit in with the code
** end-of-line comments should be spaced out and clearly apart from the code on the line
** use comments and whitespace to help with code flow and readability
* when you alter code, maintain the comments around/about it. Don't create "comment rot".
!!! On Error Handling
To err is human (and/but mess-ups can be caused by non-humans too!) - so try to anticipate the unexpected, or as Oscar Wilde said:
>To expect the unexpected shows a thoroughly modern intellect.
* errors can come from different sources:
** user error (even if you have coded a foolproof program, there is always the fool ...)
** programmer error (that's where defensive programming (see above) can help)
** exceptional circumstances (a misbehaving system, environment, etc.)
* take error handling seriously:
** raise an error when something went wrong
** detect all possible error reports/return values
** handle all detected errors appropriately
** propagate errors you cannot handle
* in order to handle errors well you need to the following information:
** where it came from
** what you were trying to do
** why it went wrong (how do you know it happened)
** when it happened
** what is its severity
** how to fix it
* you can handle errors either as soon as possible or as late as possible. Handle errors in the most appropriate context, as soon as you know enough about it to deal with it correctly.
* ways to respond to errors:
* logging it it (in a log)
* reporting it (visible to the user/caller)
* recovering from it (e.g. stopping, rolling back, pass it up the chain for handling/recovery)
* ignoring it (works wonderfully in cases here you want your code to behave in bizarre and unpredictable ways and to crash randomly)
** ignoring errors doesn't save time in the long run. You'll spend more time figuring out the causes of misbehaving programs, than you ever would have spent writing error handling code.
* when crafting error messages to users, consider the following:
** users don't thing like programmers, and usually don't have the same knowledge, so present information in a way appropriate to them
** don't use cryptic messages, or meaningless error codes
** distinguish between errors and warning - indicate the severity/implications of the problem
** if you need user input to recover or continue, ask simple, intelligible questions, and explain consequences if necessary
** make sure you follow and conform to user interface requirements and conventions/style when presenting error messages
* handling errors effectively means, you
** clean up after yourself when you detect an error
** don't leak out inappropriate information into the larger scope of the program or to the caller
** use exceptions appropriately. Throws exceptions judiciously
** consider using assertions
** make it hard for people/callers to ignore your errors (exceptions and assertions are good for this)
!!! On Testing Code
> Testing is not debugging. Don't get the two confused. They require different skills.
* __Testing__ is a methodical process of proving the existence, or lack thereof, of faults in your software.
* __Debugging__ is the act of tracking down the cause of this faulty behavior.
* If you are programming well, you will be doing a lot more testing than debugging.
* Testing should and is done at multiple levels:
** you test documents, such as requirements specifications, system/product specifications, module functional spec's, etc.
** you test code at the line, function, module, sub-system, and system/product levels
* you should always keep in mind that testing can only detect the presence of faults; it can __never__ prove the absence of defects.
** So don't be lulled into a sense of security that your code is "bug free" because it passed certain tests. Your tests may not be thorough enough or deep enough.
* testing should start as early as possible, so you can catch problems early, and when they are easy to fix
** some people write tests before they write the functional code ("test-driven development")
** create and maintain a test suit
** add tests to your suit/collection every time you find a new bug
* run your tests as often as you can ("continuous integration")
* whenever you find a bug, do the following, ''before'' you rush to fix it. The following is even more important if you ''do not'' intent on fixing it right away:
** note what you were trying to do when the failure happened
** try it again, to see if the problem is reproducible, and/or if it coincides with other conditions
** describe the fault, fully: the context, the steps, the frequency, the software version, anything else that may help reproduce/debug it
** record it in a bug tracking system, list, repository, etc.
** if possible/relevant write a simple test harness that will reproduce the problem, thus updating your test suit
!!! On Software Design
The creation of software is actually a very creative design and implementation activity, not a "mechanical" code generation.
* In the process of creating good code, you need to design the overall (system) architecture; the various components, objects, modules; data types, structures, and classes; and the various functions and methods.
* A good software design is:
** iterative - consisting of iterations of design and implementation/validation
** Cautious - not designing the "Entire Big Solution" all at once
** Realistic - pragmatic about the technologies used, as well as the methodologies and tools
** Informed - fully and deeply understanding the requirements and constraints
* A good design has:
** Simplicity - good design and code is compact ("less is more, and is not easy to achieve")
** Elegance - not baroque, clever, overly complex and confusing
** Modularity - with strong cohesion (tight related functionality within modules) and weak coupling (interdependence between modules)
** Good interfaces - clear, clean, public facades for the modules
** Extensibility - allowing for straight-forward evolution and enhancements
*** You should design for extensibility, but don't be overly general, so you don't end up designing an Operating System, not a program.
** No Duplication - Do it once. Do it well. Don't cut/copy-and-paste
** Portability - if needed (if it's a requirement/possibility)
** Idiomatic - naturally employing best practices, and fitting well with the development methodology and language used.
** Well-Documented - a good design is simple and therefore will not need a lot of documentation
----
^^1^^ Attributed to ''Napoleon'': Never ascribe to malice that which is adequately explained by stupidity.
I came across [[this blog post|http://www.chris-granger.com/2015/01/26/coding-is-not-the-new-literacy/]] by Chris Granger, and it definitely reflects my thinking about what is important to teach, and the role of Computer Science in developing [[Computational Thinking|Computational Thinking/Literacy]]. Granger draws a good parallel between literacy^^1^^ (reading/writing skills) and computation skills, namely: * Although reading and writing are the physical acts of being able to put symbols on a medium (paper, file, etc.) and retrieve those symbols, they are not the end goal of literacy. What we are aspiring for is comprehension (as a result of the act of reading), and composition (associated with the act of writing). * The equivalent of composition in Computing is the ability to successfully/meaningfully ''model'' thoughts, processes, phenomena. As it is not enough to be able to "mechanically" read and write, it is not enough to be able to code/program, run, test, debug programs. All these may be required/important, but they should not be the end goal of teaching/learning. A few points from the post: * Modeling is the new literacy * Modeling is creating a representation of a system (or process) that can be explored or used. * Defining a system or process requires breaking it down into pieces and defining those, which can then be broken down further. It is a process that helps acknowledge and remove ambiguity and it is the most important aspect of teaching people to model. * The process of creating a model is an act of discovery - we find out what pieces we need as we shape our material. * Exploration is understanding * By transposing our models to a computer, we can offload the work necessary to change, simulate, and verify. * We want a generation of writers, biologists, and accountants that can leverage computers (using domain-specific tools, concepts, frameworks, etc. - my addition) * we have to teach children how modeling happens, which we can break down into four distinct processes: ** Specification: How to break down parts ** Validation: How to test the model against the real world or against your expectations ** Debugging: How to break down bugs in a model. ** Exploration: How to then play with the model to better understand possible outcomes and to see how it could be used to predict or automate some system. * focusing on modeling pushes education towards the idea that pedagogy is really guiding children to deliberately create and explore the world around them. (Seymour Papert) And Granger finishes: >To put it simply, the next great advance in human ability comes from being able to externalize the mental models we spend our entire lives creating. > >That is the new literacy. ---- 1 - See what [[Neil Gaiman|http://www.neilgaiman.com/About_Neil]] has to say on [[The importance of having children read fiction (AND do Computing)|The importance of having children read fiction AND do Computing]]
Do you see a rider coming towards you, or riding away from you? [img[horseman|./resources/horse_small.jpg]] >If you saw the horseman coming to you, you tend to have a more optimistic mindset. If you saw the horseman riding away from you, you tend to be more of a pessimist. According to Jurriaan Kamp, the co-founder of "[[The Intelligent Optimist|http://www.theoptimist.com/]]".
In a [[Library of Congress lecture|https://www.youtube.com/watch?v=3MPSTMfAYVM]] by Michael Dirda about his book //The Classics for Pleasure// he mentioned keeping a [[commonplace book|https://en.wikipedia.org/wiki/Commonplace_book]]^^1^^, an old "knowledge management" technique, which intrigued me (como no?!). Digging a bit deeper into this old technique, I came across an interesting article by Steve Johnson titled [[The Glass Box and the Commonplace Book|https://stevenberlinjohnson.com/the-glass-box-and-the-commonplace-book-639b16c4f3bb#.w2zyf7doz]], which, I think, highlighted some parallels to new/web techniques/practices. For example: * Similar to ''blogging'': >Scholars, amateur scientists, aspiring men of letters — just about anyone with intellectual ambition in the seventeenth and eighteenth centuries was likely to keep a commonplace book. In its most customary form, “commonplacing,” as it was called, involved transcribing interesting or inspirational passages from one’s reading, assembling a personalized encyclopedia of quotations. It was a kind of solitary version of the original web logs: an archive of interesting tidbits that one encountered during one’s textual browsing. * On ''indexing and searching'': >The philosopher John Locke first began maintaining a commonplace book in 1652, during his first year at Oxford. Over the next decade he developed and refined an elaborate system for indexing the book’s content. Locke thought his method important enough that he appended it to a printing of his canonical work, An Essay Concerning Human Understanding. >[...description of the indexing scheme follows...] >Locke’s approach seems almost comical in its intricacy, but it was a response to a specific set of design constraints: creating a functional index in only two pages that could be expanded as the commonplace book accumulated more quotes and observations. In a certain sense, this is a search algorithm, a defined series of steps that allows the user to index the text in a way that makes it easier to query. * Similar to ''Pinterest'', ''Facebook'', and ''web browsing'': >The tradition of the commonplace book contains a central tension between order and chaos, between the desire for methodical arrangement, and the desire for surprising new links of association. The historian Robert Darnton describes this tangled mix of writing and reading: >>Unlike modern readers, who follow the flow of a narrative from beginning to end, early modern Englishmen read in fits and starts and jumped from book to book. They broke texts into fragments and assembled them into new patterns by transcribing them in different sections of their notebooks. Then they reread the copies and rearranged the patterns while adding more excerpts. Reading and writing were therefore inseparable activities. They belonged to a continuous effort to make sense of things, for the world was full of signs: you could read your way through it; and by keeping an account of your readings, you made a book of your own, one stamped with your personality. * On ''serendipitous data mining'': >Each rereading of the commonplace book becomes a new kind of revelation. You see the evolutionary paths of all your past hunches: the ones that turned out to be red herrings; the ones that turned out to be too obvious to write; even the ones that turned into entire books. But each encounter holds the promise that some long-forgotten hunch will connect in a new way with some emerging obsession. >[and] >The beauty of Locke’s scheme was that it provided just enough order to find snippets when you were looking for them, but at the same time it allowed the main body of the commonplace book to have its own unruly, unplanned meanderings. * On content ''remixing'' and referencing the [[Jefferson Bible|https://en.wikipedia.org/wiki/Jefferson_Bible]]: >But all of this magic was predicated on one thing: that the words could be copied, re-arranged, put to surprising new uses in surprising new contexts. By stitching together passages written by multiple authors, without their explicit permission or consultation, some new awareness could take shape. >Since the heyday of the commonplace book, there have been a few isolated attempts to turn these textual remixes into a finished product, into a standalone work of collage. The most famous is probably Jefferson’s bible, his controversial “remix” of the New Testament. * The search results page as a commonplace book: >What I want to suggest to you is that, in some improbable way, this page is as much of an heir to the structure of a commonplace book as the most avant-garde textual collage. Who is the “author” of this page? There are, in all likelihood, thousands of them. It has been constructed, algorithmically, by remixing small snippets of text from diverse sources, with diverse goals, and transformed into something categorically different and genuinely valuable. * On ''knowledge productivity'' (vs. agrarian or industrial productivity): >Ecologists talk about the “productivity” of an ecosystem, which is a measure of how effectively the ecosystem converts the energy and nutrients coming into the system into biological growth. A productive ecosystem, like a rainforest, sustains more life per unit of energy than an unproductive ecosystem, like a desert. We need a comparable yardstick for information systems, a measure of a system’s ability to extract value from a given unit of information. Call it, in this example: textual productivity. By creating fluid networks of words, by creating those digital-age commonplaces, we increase the textual productivity of the system. The overall increase in textual productivity may be the single most important fact about the Web’s growth over the past fifteen years. * On the value/desire (need?) for content/value/knowledge reuse and maximization: >The promise [of digital technology] lies in doing things with the words, forging new links of association, remixing them. We have all the tools at our disposal to create commonplace books that would astound Locke and Jefferson. >[...] >When your digital news feed doesn’t contain links, when it cannot be linked to, when it can’t be indexed, when you can’t copy a paragraph and paste it into another application: when this happens your news feed is not flawed or backwards looking or frustrating. It is broken. The author says we should not freeze the content/words (like some vendors and publishers do (and he mentions Apple, NYT, WSJ)) : >They’re frozen there, uncopyable, unlinkable, like some beautiful ice sculpture. Frozen is the right word, because we’re so used to selecting and copying digital text, encountering text on a screen that can’t be selected leaves you with a strange initial assumption: that the application has crashed, and the screen is frozen. * On the strengthening or weakening of the ''echo chamber'' effect (AKA, "the internet bubble". See also [[Minding the obvious]]): > [the "echo chamber effect" is] the premise that the internet leads to political echo chambers, where like-minded partisans reinforce their beliefs by filtering out dissenting views or in [[Cass Sunstein's words|http://www.ojr.org/ojr/glaser/1082521278.php]]: >If Republicans are talking only with Republicans, if Democrats are talking primarily with Democrats, if members of the religious right speak mostly to each other, and if radical feminists talk largely to radical feminists, there is a potential for the development of different forms of extremism, and for profound mutual misunderstandings with individuals outside the group. According to a [[David Brooks column|http://www.nytimes.com/2010/04/20/opinion/20brooks.html?hp]] reporting on a new study that actually looked an exposure to differing points of view in various forms of media, and in real-world encounters. >It turns out that the web, at least according to this study, actually reduces the echo-chamber effect, compared to real-world civic space. People who spend a lot of time on political sites are far more likely to encounter diverse perspectives than people who hang out with their friends and colleagues at the bar or the watercooler. As Brooks described it, “This study suggests that Internet users are a bunch of ideological Jack Kerouacs. They’re not burrowing down into comforting nests. They’re cruising far and wide looking for adventure, information, combat and arousal.” And the author's conclusion: >But whether or not this study proves to be accurate, one thing is certain. The force that enables these unlikely encounters between people of different persuasions, the force that makes the web a space of serendipity and discovery, is precisely the open, combinatorial, connective nature of the medium. So when we choose to take our text out of that medium, when we keep our words from being copied, linked, indexed, that’s a choice with real civic consequences that are not to be taken lightly. And: >The reason the web works as wonderfully as it does is because the medium leads us, sometimes against our will, into common places, not glass boxes. It’s our job — as journalists, as educators, as publishers, as software developers, and maybe most importantly, as readers — to keep those connections alive. ---- ^^1^^ From ~BrainPickings [[post on W. H. Auden's Commonplace Book|https://www.brainpickings.org/2016/05/10/w-h-auden-commonplace-book-doubt-truth-enchantment/]]: > the commonplace book — a creative and intellectual ledger of fragmentary inspirations, which a writer would collect from other books and copy into a notebook, often alongside his or her reflections and riffs. These borrowed ideas are in dialogue with the writer’s own imagination and foment it into original thinking. Over long enough a period of time — years, decades, often a lifetime — the commonplace book, while composed primarily of copied passages, comes to radiate the singular sensibility of its keeper: beliefs are refined, ideas incubated, intellectual fixations fleshed out, and the outlines of a personhood revealed.
[ext[Complexity - A Guided Tour|resources/Melanie-Mitchell-Complexity_a-guided-tour-366-pages.pdf]]^^1^^ <<list-links "[tag[book-chapter]!tag[Complexity - A Guided Tour]]">> ---- ^^1^^ retrieved from [[Sorrentino's blog|http://www.waltersorrentino.com.br/wp-content/uploads/2012/02/Melanie-Mitchell-Complexity_a-guided-tour-366-paginas.pdf]]
<<list-links "[tag{!!title}]">>
<a href="./resources/einstein_modeling.jpg" target="new"><img src="./resources/einstein_modeling.jpg" width="50%" height="50%" /></a> [ 1 ] On modeling: >The significant problems we face cannot be solved at the same level of thinking we were at when we created them. : -- [[Albert Einstein]] But also: >essentially, all models are wrong, but some are useful. : -- George Box and Norman Draper in their book [[Response surface methodology|http://en.wikipedia.org/wiki/Response_surface_methodology]] This activity, demonstrating modeling, is part of the [[Computational Thinking (CT) problem solving framework|A Framework for Computational Thinking, Computational Literacy]]. Modeling skills are critical in many problem solving cases, and modeling activities often happen in multiple parts of the problem solving process, as problem solvers refine their understanding of the problem (and model), as a result of new/additional data, analysis, simulation, etc. This example is using the [[VModel modeling tool|http://www.qrg.northwestern.edu/projects/NSF/Vmodel/private/]], developed as part of the [[Computer-supported Visual Representations for Learning Modeling|http://www.qrg.northwestern.edu/projects/NSF/Vmodel/index.htm]] project at Northwestern University. It is important to remember that modeling doesn't have to be computerized, but software tools are usually very helpful here ;-) !!! Building the model <a href="./resources/Termites Model 21.htm" target="new"><img src="./resources/termites_vmodel_built_small.png" width="50%" height="50%" /></a> From the [[example overview|Computational Thinking example: Termites and woodchips - overview]] certain modeling elements are emerging, and can be [ext[captured and modeled in the VModel tool|resources/termites_vmodel_built.png]]: * Entities, like: ** termites, wood chips, piles * Entity properties (characteristics, parameters), like: ** the total number of chips, termites, chips per pile, number of piles * Processes, like: ** termites picking up chips ** termites dropping off chips ** piles growing ** piles shrinking and/or vanishing * Relationships and influences, like: ** dropping off chips, may create a new pile or increase its size ** picking up chips, may eliminate a pile, or reduce its size ** as piles vanish (their size equals zero), the total number of piles decreases This modeling exercise can quickly and visually reveal what entities and relationships (for example) are of value to the modeling, i.e., what a useful level of abstraction is. For example, [ext[it is obvious from this version of the model|resources/Termites Model 5.htm]] that the individual chip and individual termite are not essential (or significantly contributing) to the model, so they can be removed. !!! Validating the model One good capability of the ~VModel tool is its ability to check the model for problems and inconsistencies. The modelers need to define the goal of the model (say, that it will explain how the total number of wood piles changes over time, as the termites pick up and drop off wood chips). Also, in addition to defining the relationships and influences between processes and properties (say, the process of termites dropping off wood chips, resulting in the creation of new piles, or the increase of the size of wood chip piles), the modelers need to define one or more predictions, and tie them to the model definition (for example, that as a result of the termite activity, the total number of piles will decrease). <a href="./resources/termites_vmodel_validated.png" target="new"><img src="./resources/termites_vmodel_validated.png" width="50%" height="50%" /></a> Now, the [ext[modeling tool can check|resources/Termites Model 2.htm]] if the model relationships as defined may indeed result in the number of piles being reduced. From my experience, the model validation is not fool-proof, but it provides some sanity checking. For example, if modelers predict that the model will result in //increasing// the total number of piles and run the validation, the [ext[tool validation algorithm detects the contradiction|resources/Termites Model 3.htm]], based on the properties and relationships. The validation algorithm can point out some finer potential problems and ambiguities with the model, like for example, if the strength of relationships or their impact is ambiguous, and can potentially both support a prediction //and// refute it. So, if the chip pick-up and drop-off processes decrease and increase the pile size //with the same impact// on the total number of piles as the pile-vanish process, [ext[the validator flags ambiguity|resources/Termites Model 4.htm]]. This is a "fine" point that can lead to insight, since when a pile vanishes, it //definitely// reduces the total number of piles, but when a wood chip is being picked up it may or may not (!) reduce the total number of piles, and that's why the strength/impact of the two processes should be set differently. ---- ^^1^^ an [[exploitable image|http://www.hetemeel.com/einsteinform.php]] of Einstein's blackboard, where you can [ext[create your own text|resources/Einstein_blackboard_exploitable.jpg]]
I recently came across an article by Mitchel Resnick (the MIT professor of Logo, Lego Mindstorms, and Scratch fame) from 1994 (!) called [ext[Learning About Life|resources/Learning About Life.html]]. He describes (among other very interesting things ;-) a situation involving termites picking up and dropping off wood chips, resulting in an interesting emerging behavior/phenomenon. I've decided to take this situation and apply my [[Computational Thinking (CT) problem solving framework|A Framework for Computational Thinking, Computational Literacy]] to demonstrate some key activities and phases in the process. As the [ext[CT framework diagram|resources/Computational Thinking process HM.pdf]] shows, the full problem solving process may include multiple activities/phases of * gathering data * defining a "good" question * coming up with a testable hypothesis * [[modeling|Computational Thinking example: Termites and woodchips - modeling]] * [[simulating|Computational Thinking example: Termites and woodchips - simulating]] * analyzing * visualizing * presenting the results and so on. !!! Data gathering The situation with the termites and wood chips described in Resnick's paper is this: <a href="./resources/Termites in HD 1080p.wmv" target="new"><img src="./resources/termites_random_walk.png" width="50%" height="50%" /></a> From observation (part of the __data gathering phase__) it seems like termites are randomly walking about in an area, picking up wood chips, carrying them for a while and dropping them off. There doesn't appear to be any leader, or pattern/trend, and after observing for a short while, no obvious purpose or result is visible. So some obvious questions come to mind: * Is there really no purpose to this seemingly random activity? * What may be a reason or result of this behavior? * Who is in control here? * Are the termites following the instructions, directives, example of someone(s)? * Will this random shuffling around of wood chips go on forever? Until the termites "get tired"? Until someone disturbs this colony? And yet, we know from other observations (__more data gathering__) that termites usually leave some marks. They sometimes create piles of wood chips, or sometimes they build big mounds (depending on the type of termite). ''It seems like the wood chips are gathered by the termites into piles, or maybe even just a __single pile__''. |borderless|k |<a href="./resources/termite_pile_1.jpg" target="new"><img src="./resources/termite_pile_1.jpg" width="60%" height="60%" /></a>|<a href="./resources/termite_pile_2.jpg" target="new"><img src="./resources/termite_pile_2.jpg" width="60%" height="60%" /></a>|<a href="./resources/termite_pile_3.jpg" target="new"><img src="./resources/termite_pile_3.jpg" width="60%" height="60%" /></a>| |borderless|k !!!So, a good set of questions to focus this investigation may be: # Is it possible that even with "random termite activity", and with no leader the termites will end up building something (piles, mounds, ''a single one'')? # Will the end result (piles, mounds) depend on the number of termites and/or the number of wood chips? # Will the end result happen at the same speed (rate) regardless of the number of termites and wood chips? In order to address the 1^^st^^ question we will use [[modeling|Computational Thinking example: Termites and woodchips - modeling]] and __simulation__ In order to address the 2^^nd^^ question we will engage in [[simulation|Computational Thinking example: Termites and woodchips - simulating]] and __analysis__ and in order to address the 3^^rd^^ question we will __analysis__ and __visualization__
This activity, demonstrating modeling, is part of the [[Computational Thinking (CT) problem solving framework|A Framework for Computational Thinking, Computational Literacy]]. Simulating skills are critical in many problem solving cases, and simulating activities often happen in multiple parts of the problem solving process, as problem solvers refine their understanding of the problem (and model), as a result of new/additional data, analysis, modeling, simulation, etc. This example is using the [[NetLogo software|http://ccl.northwestern.edu/netlogo/]], developed at Northwestern University. !!! Creating the simulation <a href="https://www.netlogoweb.org/launch#https://www.netlogoweb.org/assets/modelslib/Code%20Examples/Perspective%20Demos/Termites%20(Perspective%20Demo).nlogo" target="new"><img src="./resources/termites_netlogo_sim.png" width="50%" height="50%" /></a> From the [[example overview|Computational Thinking example: Termites and woodchips - overview]] certain simulation considerations are emerging, and can be [[captured and programmed in NetLogo|https://www.netlogoweb.org/launch#https://www.netlogoweb.org/assets/modelslib/Code%20Examples/Perspective%20Demos/Termites%20(Perspective%20Demo).nlogo]]. A few of the simulation design considerations: * From the [[modeling phase|Computational Thinking example: Termites and woodchips - modeling]], it's clear that the entities to be simulated are: termites, wood chips, and piles * In order to investigate the behavior, users need to be able to control/vary the number of termites and the number of chips * Initially, each wood chip is its own "pile", and over time chips are picked up and dropped off next to other chips, by termites following simple actions in a continuous loop: ** ''search-for-chip'' *** Each termite moves randomly through the simulation space, looking for a chip. Once it finds one, it picks it up and keeps moving randomly looking for a pile ** ''find-new-pile'' *** Once a termite carrying a chip and randomly moving encounters another chip, it assumes it's a pile and will drop it off ** ''put-down-chip'' *** Once a (chip-carrying) termite finds a pile, it looks for an empty space next to a chip belonging to that pile and drops its chip off there !!! Running the simulation Following is a series of snapshots from a simulation run, with an initial 30% chip density (about 12,000 wood chips), and 100 termites. Simulation time is measured and displayed on the chart in "clock ticks" which represent the simulation cycle updates. |borderless|k |<a href="./resources/termites_netlogo_sim1_big.png" target="new"><img src="./resources/termites_netlogo_sim1_big.png" width="50%" height="50%" /></a><br>after ~5,000 cycles, ~7,200 piles|<a href="./resources/termites_netlogo_sim2_big.png" target="new"><img src="./resources/termites_netlogo_sim2_big.png" width="50%" height="50%" /></a><br>after ~100,000 cycles, ~980 piles|<a href="./resources/termites_netlogo_sim3_big.png" target="new"><img src="./resources/termites_netlogo_sim3_big.png" width="50%" height="50%" /></a><br>after ~250,000 cycles, ~550 piles| |borderless|k As can be observed, this kind of termite behavior (or set of rules) results in pile consolidation (i.e., reduced number of piles), which is in line with [[the initial observations of real-life termite behavior|Computational Thinking example: Termites and woodchips - overview]]. Starting with about 12,000 piles, the 100 termites consolidate the chips into about 980 piles within about 100,000 simulation cycles, and then to about 550 piles after about 250,000 cycles. !!!! Exploring the simulation space <a href="./resources/termites_netlogo_BehaviorSpace.png" target="new"><img src="./resources/termites_netlogo_BehaviorSpace.png" width="50%" height="50%" /></a> One of the powerful and useful features of ~NetLogo is that it enables automatic "parameter sweeps". With a feature called [[Behavior Space|http://ccl.northwestern.edu/netlogo/docs/]], users can run a model many times, systematically varying the model's settings (or variables, like the number of termites, and the wood chip density) and recording the results of each model run. This process lets users explore the model's "space" of possible behaviors and determine which combinations of settings cause behaviors of interest. From the parameter sweep, it looks like in situations where the wood chip density is small (say 1%), pile consolidation happens relatively quickly, converging to ''a single pile'', regardless of the number of termites (or at least with the "sweep" we did of 1, 50, 100, and 150 termites). And indeed simulating with 100 termites, and 1% chip density, for about 100,000 simulation cycles results in a significant pile consolidation: <a href="./resources/termites_netlogo_sim4_big.png" target="new"><img src="./resources/termites_netlogo_sim4_big.png" width="70%" height="70%" /></a> after ~100,000 cycles, 4 piles
I recently [ext[presented about Computational Thinking (CT)|downloads/resources/Computational Literacy in the Classroom-1.pdf]]^^1^^ and provided some technology-enabled examples, at a teacher professional development session at the Ravenswood School District. I also did a similar presentation for [[Teaching Fellows for Citizen Schools|http://www.citizenschools.org/careers/teaching-fellowship/about/]]. <a href="./resources/Computational Literacy in the Classroom-1.pdf" target="new"><img src="./resources/Rosling_CNN_GapMinder1.png" width="70%" height="70%" /></a> Since addressing [[Computational Thinking|A Framework for Computational Thinking, Computational Literacy]] in school is gaining more focus, I wanted to present some impactful CT concepts and skills, in two contexts: * the (narrower) context of leveraging CT and computational technologies in __direct support__ of STEM^^2^^ standards and objectives (e.g., the [[Common Core State Standards for Mathematics|http://www.corestandards.org/]], and the [[National Framework for K-12 Science & Engineering|http://www.nap.edu/catalog.php?record_id=13165]]) * the (wider) context of introducing and supporting [[Computational Thinking|A Framework for Computational Thinking, Computational Literacy]] best practices and tools, to promote and exercise these skills and processes with students The [ext[presentation|downloads/resources/Computational Literacy in the Classroom-1.pdf]]^^1^^ demonstrated a few cases and opportunities to leverage computational technologies such as simulation, visualization, animation, and analysis tools, in support of __specific__ learning objectives and standards, but also "opening the door" to exploring and exposing new ideas and directions, by naturally "sowing seeds" through the careful planning and implementation of technology-enabled activities and experiences. !!!We also explored with the teachers: * What their educational goals were in leveraging CT and technologies * What kind of role do they see themselves play in the classroom * How comfortable are they introducing and using computational technologies as part of their curricula * What their time horizon is for learning and using CT and technologies in the classroom ---- ^^1^^ A 440KB PDF file (with the application/demo launch links disabled) ^^2^^ STEM = Science, Technology, Engineering, Mathematics
<br> `Computational Thinking is no more about computers than astronomy is about telescopes.` : -- Haggai Mark (paraphrasing Edsger Wybe Dijkstra) """ """ `Computer programming is an art, because it applies accumulated knowledge to the world, because it requires skill and ingenuity, and especially because it produces objects of beauty.` `A programmer who subconsciously views himself as an artist will enjoy what he does and will do it better.` : -- Donald Knuth """ """ <<list-links "[tag[computational-thinking-item]]">> <html> <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-nc-sa/3.0/us/88x31.png" /></a><br />To the extent possible and under my control, this work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/">Creative Commons Attribution-NonCommercial-ShareAlike 3.0 United States License</a>. </html>
In an article in The Atlantic titled [[The AI That Has Nothing to Learn From Humans|https://www.theatlantic.com/technology/archive/2017/10/alphago-zero-the-ai-that-taught-itself-go/543450/]] (2017), the author points out that the Go-playing computer program known as ~AlphaGo had been initially trained by learning from humanly played Go games. Then, when it had "enough" knowledge, it started playing against itself, in order to improve its skill and techniques even further (and faster). In the article, expert Go players made the interesting (but plausible) observation that this resulted in ~AlphaGo playing in a style which was akin to (and recognizable as) the style of human players. Then, the creators of ~AlphaGo (Google’s ~DeepMind group) built another Go-playing machine called [[AlphaGo Zero|https://deepmind.com/blog/alphago-zero-learning-scratch/]], which had been learning to play the game from scratch, without being fed any humanly played games. The author claims that >~DeepMind’s new self-taught Go-playing program [~AlphaGo Zero] is making moves that other players describe as “alien” and “from an alternate dimension.” and that there are some >"inhuman, incomprehensible elements in the way ~AlphaGo plays", as if using a playbook from an "alien civilization". Now, this sounds both intriguing and scary, and I suspect it overloads meaning on the actual fact that the playing style of ~AlphaGo Zero may indeed be different, compared to traditional/classic style. But maybe there is a non-extra-terrestrial or non-alien explanation of the different style. The game of Go is known for its enormous set of possible moves and outcomes. The number of variations of moves and counter-moves -- also known as the game decision tree -- is [[truly vast|http://www.i-programmer.info/news/112-theory/9384-number-of-legal-go-positions-finally-worked-out.html]] (approximately 2.1 * 10^^170^^, which is much, much bigger than chess^^1^^). Given that, it is conceivable that a machine such as ~AlphaGo Zero is quickly moving into areas of the decision tree (or space of possibilities/combinations) which have never been "visited" and explored/studied by human players, despite many generations of players, and years of playing and studying. I also suspect, and the Atlantic article hints about it^^2^^, that over the years and the history of the game, human players came up with stories, images, models, and myths to describe certain Go configurations, patterns, moves, and strategies. This is natural (i.e., human :), and may also lead to better understanding and memorizing certain moves and techniques for winning. But, a machine/software like ~AlphaGo Zero does not need (nor understand/relate) to these kinds of "aids" (or "crutches"). It can just "play by the numbers", so to speak, since it has the brute-force, raw number-crunching power to analyze, simulate, and calculate possibilities. Given that ~AlphaGo Zero was not fed with humanly-played games as part of its training, it just had combinations and their winning probabilities to rely on, which may explain its "alien" style of play. ---- ^^1^^ - from [[A Comparison of Chess and Go|https://www.britgo.org/learners/chessgo.html]]: >At the opening move in Chess there are 20 possible moves. In Go the first player has 361 possible moves. This wide latitude of choice continues throughout the game. At each move the opposing player is more likely than not to be surprised at their opponent's move, and hence they must rethink their own plan of attack. ^^2^^ - for example: * it’s so hard to try to attach a story about what ~AlphaGo is doing. You have to be ready to deny a lot of the things that we’ve believed and that have worked for us. * Generally the way humans learn Go is that we have a story. That’s the way we communicate. It’s a very human thing. * people can identify and discuss shapes and patterns. [...] When teaching beginners, a Go instructor might point out an odd-looking formation of stones resembling a lion’s mouth or a tortoiseshell (among other patterns) and discuss how best to play in these situations.
Computer programming is an art, because it applies accumulated knowledge to the world, because it requires skill and ingenuity, and especially because it produces objects of beauty. A programmer who subconsciously views himself as an artist will enjoy what he does and will do it better.
<<list-links "[tag{!!title}]">>
I find a parapharased version of this very apt for [[Computational Thinking|A Framework for Computational Thinking, Computational Literacy]]: Computational Thinking is no more about computers than astronomy is about telescopes The hard-boiled computer scientist [[Edsger Wybe Dijkstra]] also said: >The question of whether a computer can think is no more interesting than the question of whether a submarine can swim.
from the [[GNU software terms|https://www.gnu.org/fun/jokes/software.terms.html]] page,
"""
''Power User'': A person who has mastered the brightness and contrast controls on any computer monitor.
''Alpha software'': Too buggy to be released to the paying public.
''Beta software'': Still too buggy to be released.
''Release software'': Alternate pronunciation of "Beta software".
''Encryption'': A powerful algorithmic encoding technique employed in the creation of computer manuals.
''Multitasking (machine)'': A clever method of simultaneously slowing down the multitude of computer programs that insist on running too fast.
''Multitasking (human)'': A clever method of simultaneously slowing down all your activities and comprehension, and insisting that you are "doing great".
''Support'': The mailing of advertising literature to customers who have returned a registration card.
''Transportable'': Neither chained to a wall nor attached to an alarm system.
''Printer'': An electromechnical paper shredding device.
''Upgraded'': Didn't work the first time.
''User Friendly'': Supplied with a full color manual.
''Very User Friendly'': Supplied with a disk and audiotape so the user need not bother with the full color manual.
''Warranty'': Disclaimer.
"""
variations on the [[Error codes|https://www.gnu.org/fun/jokes/errno.2.html]] page
"""
''ENOTBACDUP'' Read on an empty pipe (ref. pipe - unix read/write channel)
''ECHERNOBYL'' Core dumped (system crashed)
''EDINGDONG '' The daemon is dead (ref. The Wizard of Oz)
''EIEIO'' Here-a-bug, there-a-bug, … (ref. Old ~McDonald had a farm)
''EMILYPOST'' Wrong fork (ref. Ms. Manners, unix fork(2), github fork)
''ENOHORSE'' Mount failed (ref. disk mounting)
''EWOK'' Aliens sighted (ref. Star Wars)
''EWOK'' Your code appears to have been stir-fried
''EWOULDBNICE'' The feature you want has not been implemented yet
"""
from [[Unix Error Messages|https://www.gnu.org/fun/jokes/unix.errors.html]]
"""
(% represents the csh, $ represents the bourne shell)
% "How poorly would you rate the Unix (so-called) user interface?
Unmatched ".
% rm congressional-ethics
rm: congressional-ethics nonexistent
% ar m God
ar: God does not exist
% [Where is Jimmy Hoffa?
Missing ].
% ^How did the sex change^ operation go?
Modifier failed.
% If I had a ( for every $ Congress spent, what would I have?
Too many ('s.
%make love
Make: Don't know how to make love. Stop.
% sleep with me
bad character
% got a light?
No match.
% man: why did you get a divorce?
man:: Too many arguments.
% ^What is saccharine?
Bad substitute.
% \(-
(-: Command not found.
% sh
$ PATH=pretending! /usr/ucb/which sense
no sense in pretending
$ drink <bottle; opener
bottle: cannot open
opener: not found
$ mkdir matter; cat >matter
matter: cannot create
Or, in a System V (att) universe:
$ cat "can of food"
cat: cannot open can of food
"""
In an excellent book titled //Will you be alive 10 years from now?// by Paul Nahin he gives quite a few examples of solving and/or demonstrating statistical and probability phenomena/questions, using MATLAB simulations/programs/code. He is happy to be flexible and use both simulations and analysis: >What I did when teaching, and have done in two previous books (//Dueling Idiots and Other Probability Puzzlers//, and //Digital Dice//), was endorse the use of computer simulation to check theoretical results. If a computer simulation of a random process agrees (to some acceptable degree) with a theoretical result, then I think one's confidence in both approaches is enhanced. Such an agreement doesn't, of course, prove that either result is correct, but surely one would then have to believe that a remarkable coincidence had instead occurred. And he observes: >There is an interesting feature to doing computer simulations that I have noticed, after decades of writing computer codes in different languages to implement them. Problems that are hard to do theoretically may require only an easy simulation; the converse may also be true, that is, a problem easy to analyze theoretically may require a complicated simulation code.
Computers are to computing as instruments are to music. Software is the score whose interpretations amplifies our reach and lifts our spirits. Leonardo da Vinci called music the shaping of the invisible, and his phrase is even more apt as a description of software. Apropos instruments vs. music vs. musician: There’s a story about Jascha Heifetz, the famously [[dyspeptic|http://www.dictionary.com/browse/dyspeptic]] Russian violinist and giant of the golden age of recording: After a concert one evening, an admirer went to visit the soloist in his dressing room. “Mr. Heifetz,” he gushed, “what a performance! Your violin has such a gorgeous tone!” Heifetz picked up his instrument, held it to his ear and knit his brow. “I don’t hear anything.”
Andrea diSessa, in his book [ext[Changing Minds: Computers, Learning, and Literacy|resources/diSessa - Changing Minds - Chapter1.pdf]], talks about the need to learn, develop, and teach what he calls "computing literacy". By that he does //not// mean things like fluency in any particular set of computer programs/applications (e.g. Microsoft Office). He compares the impact of computers, and the importance of this "new literacy" to the text-based literacy humanity experienced as a result of the introduction of the printing press and mass-produced books: >Computers can be the technical foundation of a new and dramatically enhanced literacy, which will act in many ways like current literacy and which will have penetration and depth of influence comparable to what we have already experienced in coming to achieve a mass, text-based literacy. >... >If a true computational literacy comes to exist, it will be infrastructural in the same way current literacy is in current schools. Students will be learning and using it constantly through their schooling careers, and beyond, in diverse scientific, humanistic, and expressive pursuits. Outside of schools, a computational literacy will allow civilization to think and do things that will be new to us in the same way that the modern literate society would be almost incomprehensible to preliterate cultures. Clearly by computational literacy I do not mean a casual familiarity with a machine that computes. diSessa makes a thought-inspiring analogy between the invention of the calculus (by Newton and Liebnitz) and its introduction into the core curriculum of science, engineering, and technology in universities, making it a basic ''mathematics literacy'' requirement (and assumption), and the introduction of the new ''computing literacy'', and what he expects its impact to be on humanity. >This move to infrastructural status for calculus was not easy. It took more than two centuries! In the twentieth century, a few bold universities decided it was possible and useful to teach calculus in the early and universal (for all technical students) infrastructural mode. >It succeeded, more or less, and gradually more schools jumped on the bandwagon. They had the advantage of knowing that teaching calculus this way was possible, and they could capitalize on the know-how of the early innovators. In the meantime, other professors and textbook writers for other classes began to take the teaching of calculus for granted. They became dependent on it. Calculus came to be infrastructural. His analogy between math-related literacies like algebra and calculus and computing literacy, is focusing on learners' ability to program within some sort of an environment, throughout the educational system (starting in elementary school), and into adulthood (supporting life-long learning). >We have come through expressive aptness, conceptual precision, and so on, to a really new place. From here, it is easy to imagine sixth grade students getting personally and creatively involved in designing space ships and all sorts of games. >Galileo's and Newton's sometimes forbidding abstractions have been resituated in a fabric of doing play that can be owned by children. We can be instrumental and say that mathematics and science can be motivating and engaging in a way that far transcends words, algebra, and calculus. We can talk about time on task and notions of learning through rich feedback. >Or we can say merely that we have managed to bring mathematics and science into a child's world in a way that shames you ll need this for the next course or just do the exercises. This last phrasing may be the most important. >Here is the point of this section in a nutshell. A new representational form, programming, as part of a new literacy can lead to deeper learning, much earlier with fewer unpleasant glitches, and in a way that transforms the experience of students substantially from doing what adults say in semi-comprehension into a really rich and appropriately kid-like experience, more like what they want to and can do without adults intruding awkwardly. For a different (but related) perspective in terms of //languages// (vs. literacy) see what Robert Logan has to say in his book [[The Sixth Language: Learning a Living in the Internet Age|New languages]]. (see [[article (on GD)|https://drive.google.com/open?id=1onMD8ckPHZMTQuSRSZWXm9AVwY4pfR51]]).
From //An Introduction to Computer Simulation Methods// by Harvey Gould, Jan Tobochnik, and Wolfgang Christian, and with application to Easy Java Simulations (EJS)
Since computation and computers are pervasive in science, technology, engineering, and math, and they significantly impact the way we do science, engineering, math in many cases, it is essential that we teach computing literacy as part of STEM (Science, Technology, Engineering, Math) education/programs. The availability of powerful computing technologies enables us to think differently about solving problems and leads to both new solutions and new insights/understanding of phenomena in the world.
!!!Computing capabilities
Computing (in physics, and other areas of STEM) can be leveraged in multiple areas, including numerical analysis, symbolic manipulation, visualization, simulation, and the collection and analysis of data.
* in ''numerical analysis'' computers/computing can be used to numerically solve equations and produce numerical data (e.g. solving multi-variable equations/matrices, multidimensional integrals, nonlinear differential equations, etc.)
* in ''symbolic manipulation'' computers/computing can be used to generically and symbolically solve equations, derive proofs, perform abstractions, simplifications, and approximations, etc. (e.g. performing differentiation, integration, matrix inversion, and power series expansion, etc.)
* in ''visualization'' computers/computing can be used to gain significant insights and deeper understanding of phenomena by leveraging the human capacity to quickly and effectively detect patterns in data presented and manipulated visually. Good visualizations can "bring data to life" and reveal hidden relationships and patterns.
* in ''simulation'' computers/computing can be used to develop new models of phenomena and derive new predictions, or validate/verify existing knowledge (maybe under new conditions or combinations). New insights can be gained from simulating different scenarios ("what-if" simulation and analysis).
>Simulations frequently use the computational tools of numerical analysis and visualization, and occasionally symbolic manipulation. The difference is one of emphasis. Simulations are usually done with a minimum of analysis. [...] simulation emphasizes an exploratory mode of learning.
* in ''collection and analysis of data'' computers/computing can be used to "harvest" large amounts of data (from the environment "at large", experiments, etc.) and organize, manipulate, and analyze it in different ways and under different conditions and scenarios. Combined with visualization for example, new knowledge and understanding can be gained, and possibly new models can be developed and simulated to verify or refine theories, etc.
!!!Importance of computer simulations
* most analytical methods are suited for //linear// phenomena, but unfortunately many phenomena are //non-linear//. Computers gives us a new tool to explore nonlinear phenomena.
* many interesting and useful problems and phenomena involve a large number of variables, which makes them very difficult to solve without the number crunching and symbolic manipulation capabilities of computers.
* in some cases, computer simulations enable the creation of "computer experiments" which would support lab experiments and serve as validators or testers of new/extreme/combinatorial scenarios. They can thus compliment both theory and experimentation.
>Computer simulations, like laboratory experiments, are not substitutes for thinking, but are tools that we use to understand natural phenomena. The goal of all our investigations of fundamental phenomena is to seek explanations of natural phenomena that can be stated concisely.
* Paul Nahin, in his excellent book //Will you bee alive 10 years from now?// provides many simulation code examples (about statistics and probability), and has good observations (and usage!) of both [[simulations and analysis|Computer Simulation vs. Theoretical Analysis]].
or alternatively titled: Computational disproof of mathematics questions (conjectures?) (as opposed to [[Mathematical proof by computing?]]).
In [[a question on math.stackexchange|https://math.stackexchange.com/questions/1290948/special-representation-of-a-number]], someone asked:
```
How can I check, if a number n
can be represented by pq + rs
where p,q,r,s are pairwise different prime numbers with the same number of digits.
For example,
105153899965560312960 = 3022993637 × 6003631993 + 9069920719 × 9592692301
has such a representation.
My questions :
Is such a representation (if it exists), always unique ?
How can I find the primes p,q,r,s if a representation exists ?
How can I check if a representation exists ?
```
Looking at the first question, and depending on your mindset or inclination, you may be tempted (I know I was :) to just look for a counter example, to see if representations like defined above are unique (is this the contrarian in me speaking? :) Maybe, but then again, sometimes it's easier to try to disprove something first, because then "the burden of proof" goes away :) (like the "black swan" case, where you can NEVER prove that all swans are white, but you can definitely prove that NOT all swans are white, if you find just one black swan :)
And if you know how to program, even a little bit, since it doesn't seem like a very difficult problem, you could actually write a program to brute-force search for these kinds of solutions, and see if your program can produce more than one, thus disproving uniqueness.
So here is a short Python program, which BTW is a good exercise in basic data structures (lists, dictionaries, sets):
```
# inspired by a math.stackexchange question (conjecture?):
# https://math.stackexchange.com/questions/1290948/special-representation-of-a-number
#
# n = pq + rs (whre p, q, r, s are primes with the same number of digits, and n is any number)
#
# 2 digit primes up to 50:
primes = [11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]
# the results (all n's):
ns = dict()
min_n = 0
for p in primes:
for q in primes:
for r in primes:
for s in primes:
if len(set([p, q, r, s])) == 4:
n = p * q + r * s
if not ns.get(n, False):
ns[n] = [p, q, r, s]
else:
if sorted(ns[n]) != sorted([p, q, r, s]):
print n, '=', ns[n][0], '*', ns[n][1] , '+', ns[n][2], '*', ns[n][3], '=', p, '*', q, '+', r, '*', s
if n < min_n or min_n == 0:
min_n = n
print "smallest so far:", min_n
```
and here is the output, showing a few combinations (and thus disproving the "conjecture") and finding the smallest number n = 694 = 11 * 13 + 19 * 29 = 11 * 43 + 13 * 17
```
1086 = 11 * 13 + 23 * 41 = 11 * 17 + 29 * 31
smallest so far: 1086
1086 = 11 * 13 + 23 * 41 = 11 * 17 + 31 * 29
922 = 11 * 13 + 19 * 41 = 11 * 19 + 23 * 31
smallest so far: 922
1290 = 11 * 13 + 31 * 37 = 11 * 19 + 23 * 47
922 = 11 * 13 + 19 * 41 = 11 * 19 + 31 * 23
1290 = 11 * 13 + 31 * 37 = 11 * 19 + 47 * 23
746 = 11 * 17 + 13 * 43 = 11 * 23 + 17 * 29
smallest so far: 746
746 = 11 * 17 + 13 * 43 = 11 * 23 + 29 * 17
1152 = 11 * 19 + 23 * 41 = 11 * 23 + 29 * 31
1152 = 11 * 19 + 23 * 41 = 11 * 23 + 31 * 29
846 = 11 * 13 + 19 * 37 = 11 * 29 + 17 * 31
1032 = 11 * 23 + 19 * 41 = 11 * 29 + 23 * 31
1400 = 11 * 23 + 31 * 37 = 11 * 29 + 23 * 47
846 = 11 * 13 + 19 * 37 = 11 * 29 + 31 * 17
1032 = 11 * 23 + 19 * 41 = 11 * 29 + 31 * 23
1400 = 11 * 23 + 31 * 37 = 11 * 29 + 47 * 23
874 = 11 * 13 + 17 * 43 = 11 * 31 + 13 * 41
900 = 11 * 17 + 23 * 31 = 11 * 31 + 13 * 43
732 = 11 * 13 + 19 * 31 = 11 * 31 + 17 * 23
smallest so far: 732
1038 = 11 * 17 + 23 * 37 = 11 * 31 + 17 * 41
...
1524 = 11 * 23 + 31 * 41 = 11 * 41 + 37 * 29
1268 = 11 * 17 + 23 * 47 = 11 * 41 + 43 * 19
694 = 11 * 13 + 19 * 29 = 11 * 43 + 13 * 17
smallest so far: 694
720 = 11 * 17 + 13 * 41 = 11 * 43 + 13 * 19
772 = 11 * 13 + 17 * 37 = 11 * 43 + 13 * 23
876 = 11 * 19 + 23 * 29 = 11 * 43 + 13 * 31
...
```
And if you want to use entirely unique/different/non-repeating prime numbers (p, q, r, s), you need to change 1 line
```
from: if sorted(ns[n]) != sorted([p, q, r, s]):
to: if set(ns[n]) & set([p, q, r, s]) == set():
```
to get a result starting at:
```
1704 = 11 * 17 + 37 * 41 = 13 * 19 + 31 * 47
smallest so far: 1704
1764 = 11 * 47 + 29 * 43 = 13 * 19 + 37 * 41
1764 = 11 * 47 + 29 * 43 = 13 * 19 + 41 * 37
1704 = 11 * 17 + 37 * 41 = 13 * 19 + 47 * 31
996 = 11 * 37 + 19 * 31 = 13 * 23 + 17 * 41
smallest so far: 996
1098 = 11 * 29 + 19 * 41 = 13 * 23 + 17 * 47
996 = 11 * 37 + 19 * 31 = 13 * 23 + 41 * 17
1098 = 11 * 29 + 19 * 41 = 13 * 23 + 47 * 17
1458 = 11 * 17 + 31 * 41 = 13 * 29 + 23 * 47
1458 = 11 * 17 + 31 * 41 = 13 * 29 + 47 * 23
1032 = 11 * 23 + 19 * 41 = 13 * 31 + 17 * 37
1032 = 11 * 23 + 19 * 41 = 13 * 31 + 37 * 17
1212 = 11 * 29 + 19 * 47 = 13 * 37 + 17 * 43
1814 = 11 * 41 + 29 * 47 = 13 * 37 + 31 * 43
1212 = 11 * 29 + 19 * 47 = 13 * 37 + 43 * 17
1814 = 11 * 41 + 29 * 47 = 13 * 37 + 43 * 31
1060 = 11 * 19 + 23 * 37 = 13 * 41 + 17 * 31
970 = 11 * 31 + 17 * 37 = 13 * 41 + 19 * 23
smallest so far: 970
970 = 11 * 31 + 17 * 37 = 13 * 41 + 23 * 19
1060 = 11 * 19 + 23 * 37 = 13 * 41 + 31 * 17
1262 = 11 * 29 + 23 * 41 = 13 * 43 + 19 * 37
1706 = 11 * 47 + 29 * 41 = 13 * 43 + 31 * 37
1262 = 11 * 29 + 23 * 41 = 13 * 43 + 37 * 19
1706 = 11 * 47 + 29 * 41 = 13 * 43 + 37 * 31
1002 = 11 * 41 + 19 * 29 = 13 * 47 + 17 * 23
1308 = 11 * 29 + 23 * 43 = 13 * 47 + 17 * 41
```
and so it goes ... :)
I recently came across an article by Mitchel Resnick (the MIT professor of Logo, Lego Mindstorms, and Scratch fame) from 1994 (!) called [ext[Learning About Life|resources/Learning About Life - Resnick.html]]. As expected it has numerous interesting ideas and points, but the one I want to pick here is about what he has to say on Constructionism vs. Constructivism, and some implications on simulations as educational tools (tools for learning). Resnick points out that while Constructivism (per Jean Piaget and others) studied, focused, and emphasized learning as an active process, where the learner has to create the knowledge actively and on his/her own, Constructionism (Seymour Papert and others) focused and emphasized that learning is particularly effective and powerful, if/when the learner creates "personally meaningful" or significant artifacts (and hence Papert's work with Logo, Turtle Graphics, etc.). From this, Resnick makes the important point (and almost cautions us?) that this leads to a significant difference in learning effectiveness which curricula often miss: hands-on learning activities (e.g. many Chemistry or Physics school labs/exercises) are mostly Constructivist (Piaget), since the learner in most of them "follows a recipe" (a study guide, lab instructions, a manual, etc.), and is not engaged in actively constructing personally meaningful artifacts (results, products, etc.). They are limited in how far and how deeply they can explore, since most of these learning experiences/moments/environments are "closed packages". And that's one important implication on simulations and simulation design. While simulations may be "more open" (to exploration) than say video clips (even though simulations can be inefficient as far as learning goes, in terms of flexibility/openness if they use strong scripting, prescriptions, etc.), there is only so much learners can do within their constraints (which, if designed well can be pretty weak, but still not "limitless"). A Constructionist approach would enable learners to build their own simulations, so they have a wide and deep range of exploration, and make them much more personally meaningful. For this reason, I think that it's important for learners and teachers to master "tool creation" by learning some programming, since this is bothe essential to deep learning, and is part of gaining Computational Literacy. Resnick mentions that after the great physicist and Nobel Laureate Richard Feynman died, the following sentence was found on his blackboard at Caltech: >What I cannot create, I do not understand And Resnick sees this as a strong (and lasting) endorsement of the Constructionist approach to learning/understanding. What did Feynman mean by "create" is an open question, and since he was a theoretical physicist it most probably did not mean //physically// create/produce. It is interesting that a less often quoted sentence on Feynman's blackboard [img[Feynman's blackboard|resources/Feynman_blackboard.jpg]], right before the first one was: >know how to solve every problem that has been solved To me these two are tied together and possibly indicate what he meant by "creating". If a learner wants to //really//, //truly// understand something, they have to work it out personally, take nothing on faith or for granted, and work as much as possible from first principles, and build up from there. Another benefit of recreating (or personally creating) is that you gain a more intuitive understanding; the knowledge "sits better" with you, since you worked out and personally experienced the difficulties, discoveries, nuances, etc. (for another Feynman anecdote about creating/constructing and its power see [[Looking for patterns]]). This reminds me of a job interview I had as a hardware electronics engineer. The interviewer asked me if I know the formula for calculating the gain/amplification of a certain operational amplifier configuration. I wasn't sure, but I told him that I can work it out, if he gives me a couple of minutes, and I arrived at the formula from first principles. He looked satisfied (and I got the job).
In an article titled [[Putting Students on the Path to Learning - The Case for Fully Guided Instruction|https://www.aft.org/sites/default/files/periodicals/Clark.pdf]] the authors ( Richard E. Clark, Paul A. Kirschner, and John Sweller) make an important observation and distinction about Constructivism: >[M]any educators mistakenly believe partially and minimally guided instructional approaches are based on solid cognitive science. Turning to Mayer’s review of the literature [see below], many educators confuse “constructivism,” which is a theory of how one learns and sees the world, with a prescription for how to teach. In the field of cognitive science, constructivism is a widely accepted theory of learning; it claims that learners must construct mental representations of the world by engaging in active cognitive processing. >Many educators (especially teacher education professors in colleges of education) have latched on to this notion of students having to “construct” their own knowledge, and have assumed that the best way to promote such construction is to have students try to discover new knowledge or solve new problems without explicit guidance from the teacher. Unfortunately, this assumption is both widespread and incorrect. Mayer calls it the “constructivist teaching fallacy.” >Simply put, cognitive activity can happen with or without behavioral activity, and behavioral activity does not in any way guarantee cognitive activity. In fact, the type of active cognitive processing that students need to engage in to “construct” knowledge can happen through reading a book, listening to a lecture, watching a teacher conduct an experiment while simultaneously describing what he or she is doing, etc. >Learning requires the construction of knowledge. Withholding information from students does not facilitate the construction of knowledge. Or in Richard Mayer's words (from his article [[Should There Be a Three-Strikes Rule Against Pure Discovery Learning? The Case for Guided Methods of Instruction|http://projects.ict.usc.edu/itw/gel/MayerThreeStrikesAP04.pdf]]): >[T]he failure of pure discovery as a method of instruction does not necessarily mean that constructivism is wrong as a theory of learning or that hands-on activity is necessarily a wrong method of instruction. A basic premise in constructivism is that meaningful learning occurs when the learner strives to make sense of the presented material by selecting relevant incoming information, organizing it into a coherent structure, and integrating it with other organized knowledge (Mayer, 2003). It follows that instructional methods that foster these processes will be more successful in promoting meaningful learning than instructional methods that do not. Mayer finds guided discovery more effective than pure discovery: >In many ways, guided discovery appears to offer the best method for promoting constructivist learning. The challenge of teaching by guided discovery is to know how much and what kind of guidance to provide and to know how to specify the desired outcome of learning. In some cases, direct instruction can promote the cognitive processing needed for constructivist learning, but in others, some mixture of guidance and exploration is needed. This is a lesson that emerges again within the context of learning in social context. Mayer, like the authors above distinguishes between activities that involve only behavioral aspects and activities which promote cognitive work: >Activity may help promote meaningful learning, but instead of behavioral activity per se (e.g., hands-on activity, discussion, and free exploration), the kind of activity that really promotes meaningful learning is cognitive activity (e.g., selecting, organizing, and integrating knowledge). >Instead of depending solely on learning by doing or learning by discussion, the most genuine approach to constructivist learning is learning by thinking. Methods that rely on doing or discussing should be judged not on how much doing or discussing is involved but rather on the degree to which they promote appropriate cognitive processing. >Guidance, structure, and focused goals should not be ignored. This is the consistent and clear lesson of decade after decade of research on the effects of discovery methods. In their research paper focusing on learning assessments titled [[Constructivism in an Age of NonConstructivist Assessments|http://aaalab.stanford.edu/papers/Constructivist_Assessments_Final.pdf]], Daniel Schwartz, Robb Lindgren, and Sarah Lewis makes the following observations about constructivism: >In our experience, constructivism tends to be too large and general a philosophy to be useful for the precise handling of the many specific ways and reasons that people learn. Constructivism is not at the right level for deriving specific instructional decisions. Sometimes hands-on learning is valuable and sometimes it is not—knowing the microscopic details of when it is valuable is difficult to derive from constructivism alone. >This is not to say that constructivism does not have an important role to play in the design of instruction. In other words, Schwartz et al., see Constructivism as a Guide to Assessment: >Although we believe that the broad concept of constructivism invites the wrong level of analysis for designing specific instructional moments, we do see constructivism as extremely valuable when applied to learning outcomes. Rather than taking constructivism as an instructional design theory, we suggest that the ideas of constructivism be applied to assessment. We ask the question “Does instruction prepare learners to construct knowledge once we no longer orchestrate specific instructional conditions to target specific learning mechanisms and outcomes?”. And that's where they see Preparing for Future Learning (PFL) as the more appropriate way to assess: >A more appropriate test for constructivist outcomes is a preparation for future learning (PFL) assessment. In this type of assessment, students have an opportunity to learn during the test itself. Students who have been prepared to construct new knowledge in a domain will learn more during the assessment than those who have not been prepared to learn. PFL measures seem more in line with constructivist outcomes. Schwartz points out that there is no one "correct way of teaching": > Sometimes, it is important to explore and develop one’s own ideas. Sometimes, it is important to receive direct guidance. The question is not which method is right; the question is what combination of methods is best for a given outcome. >Direct instruction can be very effective, assuming that people have sufficient prior knowledge to construct new knowledge from what they are being told or shown. In many cases, they do not. >[...] a good way to prepare students for direct instruction is to give them targeted experiences with “exploratory” activities. And a comment on worked out (solved) examples: >worked examples can create effective instruction, but only if students are prepared to construct useful knowledge from the examples. Schwartz et al. summarize (added formatting is mine): When students engage in the inquiry and exploratory activities that comprise much of constructivist instruction, they are also __engaging ''contrasting cases''__. For example, they may notice that two different actions lead to two different effects. A risk of poorly developed inquiry activities is that there can be too many contrasts, some less useful than others. While a broad range of possible contrasts will uncover many interesting and useful student ideas, too many contrasts make it difficult for students to discern which variables and interactions are most important. Moreover, in large classes, different students may follow the implications of different contrasts, which will make it difficult to “pull it together” for all the students in a class. In our approach, we pre-figure the contrasts to simplify the instructional task. __A second important feature__ was that the students were asked to ''invent representations'' for the cases, whether symbolic procedures or graphs. This was important for four reasons: 1 - The first, as demonstrated by Sears, is that students will not notice the structures highlighted by the contrasts if they are told at the outset how to use the correct procedure. They will focus on the procedure rather than the situational structures that make the procedure useful. Inventing the procedure focuses them on the situation and the procedural issues. 2 - The second reason is that invention prepares students to appreciate the “why” captured inside the canonical solution. By working to invent solutions themselves, they begin to understand the issues that led to the design of the expert theory or procedure. 3 - The third reason for having students do representational activities is that the goal of much school instruction is to help students learn to understand and use the compact symbolic representations and theories that experts use to organize complexity. Having students work towards these representations sets the stage for learning the canonical accounts. 4 - A final reason for the invention activities is that students enjoy them, and there appears to be more engaged thinking and positive effects as a result. Students treat these activities as original production activities that promote creative thinking through the exploration of possible solution paths and representational artifacts. The solutions that students produce are sometimes suboptimal, but in general, students are not wrong in their inventions. Rather, their inventions simply do not handle all the cases or generalize to cases yet to be seen. When confronted with their “partial accuracy” students come to appreciate their own work, the work of others, and the standard solution. __[T]he third important feature__ that we have emphasized here is the eventual ''delivery of a comprehensive account of the cases''. The goal is to prepare students to understand the account. And importantly: ''The activities we have described are __not discovery activities in the sense of expecting students to discover the canonical solutions on their own__.''
Matthias Felleisen (at Northeastern University^^1^^) [[writes|http://www.ccs.neu.edu/home/matthias/Thoughts/What_should_the_core_achieve_.html]] on [[his website|http://www.ccs.neu.edu/home/matthias/]]: >The core courses of a computer science curriculum should equip an undergraduate with ''//the//'' mindset and ''//a//'' tool set to tackle software design problems. * A CS graduate should internalize and routinely use the "software design process"^^2^^ when working on projects: ** gather and organize data ** work through examples to clarify ambiguities and to get an idea about the solution ** translate the organization of the problem data into an organization of the solution ** tackle the solution proper ** test the solution for correctness and other constraints * The graduate should be aware of and address as appropriate, non-functional constraints on projects (e.g., performance, scaling, resource consumption). And when dealing with constraints the student should: ** conduct measurements to find “hot spots” ** followed by a diagnosis step ** and ideally resolved with the use of standard solutions (instead of custom/novel ones, if possible, since they are more maintainable) * The student should be a life-long learner and feel comfortable learning new programming languages and/or new programming environments ** in the real world, any big project/system may/will employ multiple languages and development tools ** in real life, a long and successful professional career will require learning new languages, tools, and environments * The graduate should acquire a tool set consisting of ** several programming languages ** the typical range of important data structures and algorithms ** the practical experience with some tools to find “hot spots” ** the theoretical knowledge to analyze and resolve these problems (“hot spots”) ---- ^^1^^ In a typical curriculum, the core includes two courses on programming, two courses on discrete data structures and algorithms, and a course on hardware platforms. At Northeastern, it also includes a course on logic in programming. ^^2^^ This is taught from the book (by Felleisen et al.) //How to Design Programs// (~HtDP) [[available online|http://www.ccs.neu.edu/home/matthias/HtDP2e/]]
In a clear and sound 1990 [[article in Scientific American|http://www.cs.bu.edu/~snyder/cs109/CouldAMachineThink.pdf]], the authors Paul Churchland and [[Patricia Churchland|http://patriciachurchland.com/]]^^1^^ compare the famous Chinese Room thought experiment by John Searle to a made-up parallel thought experiment, to show the flaws in Searle's argument/logic (an argument which I never thought valid (just saying :) ). The Chinese Room experiment as they describe it: >In 1980 John Searle authored a criticism aimed at the most basic assumption of the classical research program: the idea that the appropriate manipulation of structured symbols by the recursive application of structure-sensitive rules could constitute conscious intelligence. > >Searle's argument is based on a thought experiment that displays two crucial features. First, he describes a SM machine that realizes, we are to suppose, an input-output function adequate to sustain a successful Turing test conversation conducted entirely in Chinese. Second, the internal structure of the machine is such that, however it behaves, an observer remains certain that neither the machine nor any part of it understands Chinese. AIl it contains is a monolingual English speaker following a written set of instructions for manipulating the Chinese symbols that arrive and leave through a mail slot. In short, the system is supposed to pass the Turing test, while the system itself lacks any genuine understanding of Chinese or real Chinese semantic content [see "Is the Brain's Mind a Computer Program? " by John R. Searle, page 26). > >The general lesson drawn is that any system that merely manipulates physical symbols in accordance with structure-sensitive rules will be at best a hollow mock-up of real conscious intelligence, because it is impossible to generate "real semantics" merely by cranking away on "empty syntax." Here, we should point out, Searle is imposing a nonbehavioral test for consciousness: the elements of conscious intelligence must possess real semantic content. > >One is tempted to complain that Searle's thought experiment is unfair because his Rube Goldberg system will compute with absurd slowness. Searle insists, however, that speed is strictly irrelevant here. A slow thinker should still be a real thinker. Everything essential to the duplication of thought, as per classical AI, is said to be present in the Chinese room. And its assumptions/axioms: >THE CHINESE ROOM >Axiom 1. Computer programs are formal (syntactic). >Axiom 2. Human minds have mental contents (semantics). >Axiom 3. Syntax by itself is neither constitutive of nor sufficient for semantics. > >Conclusion 1. Programs are neither constitutive of nor sufficient for minds. And the parallel thought experiment the authors call "Luminous Room": >Imagine this argument raised shortly after James Clerk Maxwell's 1864 suggestion that light and electromagnetic waves are identical but before the world's full appreciation of the systematic parallels between the properties of light and the properties of electromagnetic waves. This argument could have served as a compelling objection to Maxwell's imaginative hypothesis, especially if it were accompanied by the following commentary in support of axiom 3. > >"Consider a dark room containing a man holding a bar magnet or charged object. If the man pumps the magnet up and down, then, according to Maxwell's theory of artificial luminance (AL), it will initiate a spreading circle of electromagnetic waves and will thus be luminous. But as all of us who have toyed with magnets or charged balls well know, their forces (or any other forces for that matter), even when set in motion, produce no luminance at all. It is inconceivable that you might constitute real luminance just by moving forces around!" And its assumptions/axioms: >THE LUMINOUS ROOM >Axiom 1. Electricity and magnetism are forces. >Axiom 2. The essential property of light is luminance. >Axiom 3. Forces by themselves are neither constitutive of nor sufficient for luminance. > >Conclusion 1. Electricity and magnetism are neither constitutive of nor sufficient for light. So, >How should Maxwell respond to this challenge? He might begin by insisting that the "luminous room" experiment is a misleading display of the phenomenon of luminance because the frequency of oscillation of the magnet is absurdly low, too low by a factor of 10^^15^^. This might well elicit the impatient response that frequency has nothing to do with it, that the room with the bobbing magnet already contains everything essential to light, according to Maxwell's own theory. > >In response Maxwell might bite the bullet and claim, quite correctly, that the room really is bathed in luminance, albeit a grade or quality too feeble to appreciate. (Given the low frequency with which the man can oscillate the magnet, the wavelength of the electromagnetic waves produced is far too long and their intensity is much too weak for human retinas to respond to them.) But in the climate of understanding here contemplated the 1860's-this tactic is likely to elicit laughter and hoots of derision. "Luminous room, my foot, Mr. Maxwell. It's pitch-black in there!" > >Alas, poor Maxwell has no easy route out of this predicament. All he can do is insist on the following three points. First, axiom 3 of the above argument is false. Indeed, it begs the question despite its intuitive plausibility. Second, the luminous room experiment demonstrates nothing of interest one way or the other about the nature of light. And third, what is needed to settle the problem of light and the possibility of artificial luminance is an ongoing research program to determine whether under the appropriate conditions the behavior of electromagnetic waves does indeed mirror perfectly the behavior of light. And the conclusion/parallel to Searle's criticism of Artificial Intelligence (AI) efforts: >This is also the response that classical AI should give to Searle's argument. Even though Searle's Chinese room may appear to be "semantically dark," he is in no position to insist, on the strength of this appearance, that rule-governed symbol manipulation can never constitute semantic phenomena, especially when people have only an uninformed commonsense understanding of the semantic and cognitive phenomena that need to be explained. Rather than exploit one's understanding of these things, Searle's argument freely exploits one's ignorance of them. BRILLIANT!!! ---- ^^1^^ - Patricia Churchland is mentioned in the book [[The Meaning of Human Existence|https://www.washingtonpost.com/opinions/book-review-the-meaning-of-human-existence-by-edward-o-wilson/2014/11/14/deffe5bc-548f-11e4-809b-8cc0a295c773_story.html]] by Edward O. Wilson, where he commends her and Daniel Dennett on clear-eyed use of neuroscience to shed light on conscientiousness.
Courage is rightly esteemed the first of human qualities... because it is the quality which guarantees all others.
In [[a sound interview|http://www.criticalthinking.org/pages/an-interview-with-linda-elder-about-using-critical-thinking-concepts-and-tools/495]] on her [[website critical thinking|http://www.criticalthinking.org/]], Linda Elder succinctly answers the question: ''What critical thinking skills do we need to foster in terms of information on the World Wide Web?'' (reformatting is mine) To effectively use information available to us on the web, we need basic critical thinking skills to analyze, evaluate, and improve thinking. In other words, we need to be able to figure out: * the agenda of the website, * the questions they are purporting to answer, * the information being presented, * the assumptions made, * the key concepts that drive the positions taken, etc. But perhaps even more importantly, we need to be able to assess the quality of website material. For example, * we need to be able to figure out whether the information is accurate, and hence how we could check to see if it is accurate. * We need to be able to figure out whether it is relevant to the issue we are focused on. * We need to be able to distinguish between information that is deep and that which is superficial. * We need to differentiate between the significant and the insignificant. * We need to be able to determine whether the information provided is detailed enough (or precise enough) for our purpose, etc.
Here are a few excerpts from Richard Hamming's talk [[One Man's View of Computer Science|http://worrydream.com/refs/Hamming%20-%20One%20Man's%20View%20of%20Computer%20Science.pdf]], about a CS curriculum proposal created by the ACM in 1968 (!). At times the content is "colored/tainted by history", but overall, I think that he looks at it the right way: >Like writing, programming is a difficult and complex art. Few programmers write in flowing poetry; most write in halting prose. >I doubt that style in programming is tied very closely to any particular machine or language, any more than good writing in one natural language is significantly different than it is in another. There are, of course, particular idioms and details in one language that favor one way of expressing the idea rather than another, but the essentials of good writing seem to transcend the differences in the Western European languages with which I am familiar. And I doubt that it is much different for most general purpose digital machines that are available these days. >I would require every computer science major, undergraduate or graduate, to take a stiff laboratory course in which he designs, builds, debugs, and documents a reasonably sized program, perhaps a simulator or a simplified compiler for a particular machine. >The results would be judged on style of programming, practical efficiency, freedom from bugs, and documentation. If any of these were too poor, I would not let the candidate pass. In judging his work we need to distinguish clearly between superficial cleverness and genuine understanding. Cleverness was essential in the past; it is no longer sufficient. > >I would also require a strong minor in some field other than computer science or mathematics. Without real experience in using the computer to get useful results the computer science major is apt to know all about the marvelous tool except how to use it. Such a person is a mere technician, skilled in manipulating the tool but with little sense of how and when to use it for its basic purposes. I believe we should avoid turning out more idiot savants -- we have more than enough "computniks" now to last us a long time. >What we need are professionals! >Let me now turn to the delicate matter of ethics. It has been observed on a number of occasions that the ethical behavior of the programmers in accounting installations leaves a lot to be desired when compared to that of the trained accounting personnel. We seem not to teach the "sacredness" of information about people and private company material. > >We should look at, and copy, how ethical standards are incorporated into the traditional accounting courses (and elsewhere), because they turn out a more ethical product than we do. We talk a lot in public of the dangers of large data banks of personnel records, but we do not do our share at the level of indoctrination of our own computer science majors. >I believe these three topics -- ethics, professional behavior, and social responsibility must be incorporated into the computer science curriculum. And he concludes: >We are now well started, and it is time to deepen, strengthen, and improve our field so that we can be justly proud of what we teach, how we teach it, and of the students we turn out. We are not engaged in turning out technicians, idiot savants, and comput: niks; we know that in this modern, complex world we must turn out people who can play responsible major roles in our changing society, or else we must acknowledge that we have failed in our duty as teachers and leaders in this exciting, important field -- computer science.
The [[Edgie, Daniel Dennett|https://www.edge.org/memberbio/daniel_c_dennett]], is [[talking about Computational Perspective|https://www.edge.org/conversation/daniel_c_dennett-the-computational-perspective]], in which he describes a fruitful technique ("thought experiment habit", or [["intuition pump"|https://www.edge.org/conversation/intuition-pumps]]?), which he calls //the intentional stance//^^1^^:
>It's a strategy you can try whenever you're confronted with something complex in nature it doesn't always work. The idea is to interpret that complexity as one or more intelligent, rational agents that have agendas, beliefs, and desires, and that are interacting. When you go up to the intentional level, you discover patterns that are highly predictive, that are robust, and that are not reducible in any meaningful sense to the lower-level patterns at the physical level. In between the intentional stance and the physical stance is what I call the design stance. That's the level of software.
He explains that this level, while (possibly only?) "human-made", is real, in a real/meaningful sense:
>[This level consists of patterns, and] what explains their very existence in the universe is computation, is the algorithmic quality of all things that reproduce and that have meaning, and that make meaning.
>These patterns are not, in one sense, reducible to the laws of physics, although they are based in physical reality, although they are patterns in the activities and arrangements of physical particles. The explanation of why they form the patterns they do has to go on at a higher level.
And he gives and example which comes from Douglas Hofstadter, showing how ONLY by going up to the intentional level, can we understand/explain certain real/physical/lower level phenomena:
>We come across a computer and it's chugging along, chugging along; it's not stopping. And our question is: Why doesn't it stop? What fact explains the fact that this particular computer at this time doesn't stop? And in Doug's example, the answer is that reason it doesn't stop is that pi is irrational! What? Well, the number pi is an irrational number, which means it's a never-ending decimal, and this particular computer program is generating the decimal expansion of pi, a process that will never stop. Of course, the computer may break. Somebody may come along with an ax and cut the cord so it doesn't have any more power, but as long as it keeps being powered, it's going to go on generating these digits forever. That's a simple concrete fact that can be detected in the world, the explanation of which cites an abstract mathematical fact about a particular number that is an irrational number.
''And this, I think, explains the usefulness (in addition to the beauty, and joy) of computing.''
In the article, Dennett also gives his (seeming tongue-in-cheek, but nonetheless illuminating :) definition of ''algorithm'':
>An algorithm is an abstract process that can be defined over a finite set of fundamental procedures, an instruction set. It is a structured array of such procedures. That's a very generous notion of algorithm—more generous than many mathematicians would like, because I would include by that definition algorithms that may be in some regards defective. Consider your laptop. There's an instruction set for that laptop, consisting of all the different basic things that your laptop's CPU can do; each basic operation has a digital name or code, and every time that bit-sequence occurs, the CPU tries to execute that operation. You can take any bit sequence at all, and feed it to your laptop, as if it were a program. Almost certainly, any sequence that isn't designed to be a program to run on that laptop won't do anything at all — it'll just crash. Still, there's utility in thinking that any sequence of instructions, however buggy, however stupid, however pointless, should be considered an algorithm, because one person's buggy, dumb sequence is another person's useful device for some weird purpose, and we don't want to prejudge that question. (Maybe that "nonsense" was included in order to get the laptop to crash at just the point it crashed!) One can define a more proper algorithm as one which runs without crashing. The only trouble is that if you define algorithm that way, then probably you don't have any on your laptop, because there's almost certainly a way to make almost every program on your laptop crash. You just haven't found it yet. Bug-free software is an ideal that's almost never achieved.
From here, Dennett goes on to try and define (or not :) the boundaries around what should be considered computational (and address the (vacuous, but heard-of) claim that "everything is computation"):
>Looking at the world as if everything is a computational process is becoming fashionable. Here one encounters not an issue of fact, but an issue of strategy. The question isn't, "What's the truth?" The question is, "What's the most fruitful strategy?" You don't want to abandon standards and count everything as computational, because then the idea loses its sense. It doesn't have any grip any more. How do you deal with that? One way is to try to define, in a rigid centralist way, some threshold that has to be passed, and say we're not going to call it computational unless it has properties A, B, C, D, and E. That's fine, you can do that in any number of different ways, and that will save you the embarrassment of having to say that everything is computational. The trouble is that anything you choose as a set of defining conditions is going to be too rigid. There are going to be things that meet those conditions that are not interestingly computational by anybody's standards, and there are things that are going to fail to meet the standards, which nevertheless you see are significantly like the things that you want to consider computational. So how do you deal with that? By ignoring it, by ignoring the issue of definition, that's my suggestion. Same as with life! You don't want to argue about whether viruses are alive or not; in some ways they're alive, in some ways they're not. Some processes are obviously computational. Others are obviously not computational. Where does the computational perspective illuminate? Well, that depends on who's looking at the illumination.
I find his approach and treatment of the question above wise ("True", "Real"), Buddhist-like ("accepting", "understanding", "accommodating"), and scientific ("practical", "rational", "goal-oriented"), all at the same time; most things in life are really open-ended and even if considered objective, stem from our human (como-no?!) perspective. That's the inevitable strength and weakness of the "human condition".
Dennett succinctly describes the layers or lenses through which he is looking at reality:
>I describe three stances for looking at reality: the physical stance, the design stance, and the intentional stance.
>__The physical stance__ is where the physicists are, it's matter and motion.
>__The design stance__ is where you start looking at the software, at the patterns that are maintained, because these are designed things that are fending off their own dissolution. That is to say, they are bulwarks against the second law of thermodynamics. This applies to all living things, and also to all artifacts.
>Above that is __the intentional stance__, which is the way we treat that specific set of organisms and artifacts that are themselves rational information processing agents. In some regards you can treat Mother Nature -- that is, the whole process of evolution by natural selection -- from the intentional stance, as an agent, but we understand that that's a façon de parler, a useful shortcut for getting at features of the design processes that are unfolding over eons of time. Once we get to the intentional stance, we have rational agents, we have minds, creators, authors, inventors, discoverers and everyday folks interacting on the basis of their take on the world.
The (not-so-subtle, I think) point Dennett makes here is that he doesn't claim that "rational agents, we have minds, creators, authors, inventors, discoverers" and so on are actual things like at the physical layer. They are things we //define// (for utilitarian purposes) at the intentional level, using this ascent on the ladder of abstraction as a tool, circumventing the (unanswerable?) question of "do these things 'really' exist?"
And he then asks, if there is a stance/level above the 3 he identified above, concluding that there is: the moral stance:
>A person is a moral agent, not just a cognitive agent, not just a rational agent, but a moral agent. And this is the highest level that I can make sense of. And why it exists at all, how it exists, the conditions for its maintenance, are very interesting problems.
And this stance results in different ways of looking at things, behaving, and drawing conclusions (compared to the lower levels/stances):
>But when we look at game theory as applied not just to rational agents, but to people with a moral outlook, we see some important differences. People have free will. Trees don't. [Considerations of zero-sum-games, win-win, etc., are] not an issue for trees in the way [they are] for people.
On "treading carefully" and responsibly when searching for truths:
>I've come to respect the cautious conservatism that many people express — and some even live by — which says that the environmental impact of these new ideas is not yet clear and that you should be very careful about how you introduce them. Don't fix what isn't broke. Don't let your enthusiasm for new ideas blind you to the possibility that maybe they will undo something of long standing that is really valuable. That's an idea that is seldom articulated carefully, but that, in fact, drives many people. And it's an entirely honorable motivation to be concerned that some of our traditional ideas are deeply threatened by these innovations of outlook, and to be cautious about just trading in the old for the new. Indeed I think that's wise. Environmental impact statements for scientific and philosophical advances should be taken seriously. There might be a case of letting the cat out of the bag in a way that would really, in the long run, be unfortunate. Anybody who appreciates the power of ideas realizes that even a true, or well founded, idea can do harm if it is presented in an unfortunate context. What I mainly object to is the way some people take it unto themselves to decide just which ideas are dangerous, and then decide that they're justified in going out and beating those ideas up with whatever it takes: misleading descriptions, misrepresentations, character assassinations and so forth.
----
^^1^^ - see also [[What could a neuron want?|pg. 14 - DANIEL DENNETT: WHAT COULD A NEURON "WANT"?]]
In a very well written [[review of the book Dark Matter and the Dinosaurs|http://www.nytimes.com/2015/11/29/books/review/dark-matter-and-the-dinosaurs-by-lisa-randall.html]] by Lisa Randall, Maria Popova of [[Brain Pickings|https://www.brainpickings.org]] uses evocative language to highlight a few things which caught my eye (mind, and memory): * In the book Randall has "an original theory that builds on a century of groundbreaking discoveries to tell the story of how the universe as we know it came to exist, how dark matter illuminates its beguiling unknowns and how the physics of elementary particles, the physics of space, and the biology of life intertwine in ways both bewildering and profound." * Popova observes about Randall's theory: > A good theory is an act of the informed imagination - - it reaches toward the unknown while grounded in the firmest foundations of the known. * Popova also comments on Randall's description of the process of scientific discovery: > Almost more interesting than the theory itself is Randall’s tour of the process of scientific endeavor, in which scientists traverse the abyss between the known and the unknown, suspended by intuition, adventurousness, a large dose of stubbornness and a measure of luck. * Dark Matter plays a critical role in Randall's theory: > Dark matter is the invisible cosmic stuff that, like ordinary matter - - which makes up the stars and the stardust, you and me and everything we know — interacts with gravity but, unlike ordinary matter, doesn’t interact with light. Although scientists know that dark matter exists and accounts for a staggering 85 percent of the universe - - billions of dark-matter particles are passing through you this very second - - they don’t yet know what it’s made of. For Randall the possibilities within that mystery are among the most thrilling frontiers of human knowledge. * Randall calls the force driving that fraction of the matter of the universe “dark light” - - an appropriately paradoxical term confuting the haughty human assumption that the world we see is all there is. * and speaking of "paradoxical" terms and theories: > the physicist Brian Josephson [wrote] about Einstein’s famous conversation with the Indian philosopher Rabindranath Tagore: “We Think That We Think Clearly, but That’s Only Because We Don’t Think Clearly.” * In an aside on the seemingly diminishing demands our culture puts on our minds, making them more feeble, Popova says: > While you need not be a physicist to metabolize the narrative [of a new scientific theory], you are certainly called upon to do your own chewing - - a rare opportunity in a culture where we are taken for so intellectually inept that our own conclusions are fed to us in listicles of bite-size buzz. ** I'm actually not sure that lowering the standards is a general cultural trend; I think that it's similar to our dietary choices: some people will always gravitate towards "junk food" while others will carefully watch what they put in their mouths (and possibly what comes out of it, as well ... :) * “Extinctions,” Randall writes, “destroy life, but they also reset the conditions for life’s evolution.” The universe is strewn with dualities, which Randall insightfully exposes. ** The existence of parallel truths is what gives our world its tremendous richness, and the grand scheme of things is far grander than our minds habitually imagine. ** which reminds me of a saying by the physicist Niels Bohr^^1^^: > The opposite of a fact is falsehood, but the opposite of one profound truth may very well be another profound truth. * Popova concludes by commenting on science and truth: > Science, after all, isn’t merely about advancing information — it’s about advancing understanding. Its task is to disentangle the opinions and the claims from the facts in the service of truth. But beyond the “what” of truth, successful science writing tells a complete story of the “how” — the methodical marvel building up to the “why” — and Randall does just that. ---- 1 - I think that Einstein would have agreed with Bohr on this^^2^^. From one perspective, Einstein's theory of relativity could be considered a contradiction of Newton's "classic" theory of mechanics. But, this may be viewed as a case where two seemingly contradictory theories are both true, but under different conditions (Newton's is good for slow speeds of bodies in motion, while Einstein's holds for high speed motion). What Einstein and Bohr had a disagreement on was another theory: Quantum Mechanics. Einstein very much disagreed about the statistical nature of the theory and commented: God does not play dice (when it comes to the laws governing nature). Presumably, Bohr responded with a great comeback: stop telling God what to do with his dice. ^^2^^ - regarding understanding among "Physics Greats": there is this anecdote about [[Sir Arthur Eddington|https://en.wikipedia.org/wiki/Arthur_Eddington]], who when asked if only three people in the world understood general relativity replied, “Who is the third?”
In one of the Computer Science courses I had developed and I currently teach (using Python as the programming language), there is a unit on data structures (which are an essential part of the craft and science^^1^^).
As [[Fred Brooks|https://www.wired.com/2010/07/ff_fred_brooks/]] (a "[[CS Sage|https://en.wikipedia.org/wiki/List_of_computer_scientists]]", and the author of the excellent book [["The Mythical Man-Month"|http://www.cs.cmu.edu/~15712/papers/mythicalmanmonth00fred.pdf]]) had said:
* "Show me your code and conceal your data structures, and I shall continue to be mystified. Show me your data structures, and I won't usually need your code; it'll be obvious." and
* "Smart data structures and dumb code works a lot better than the other way around."
We start with a very basic (but extremely versatile -- see the [[LISP programming language|https://en.wikipedia.org/wiki/Lisp_(programming_language)]] :) data structure: the [[list|https://en.wikipedia.org/wiki/List_(abstract_data_type)]].
One of the assignments on lists is to code the logic of a simple game (the hand game [["Morra"|https://en.wikipedia.org/wiki/Morra_(game)]]) and program the determination of the winner using lists instead of [[conditionals|https://en.wikipedia.org/wiki/Conditional_(computer_programming)]] (i.e., no use of if/then/else).
This can be "elegantly" done by capturing the "win/lose payoff matrix (table)" as a list of lists (here is the Python syntax):
{{{
winner = [ ["tie", "player 1", "player 2", "tie"],
["player 2", "tie", "tie", "player 1"],
["player 1", "tie", "tie", "player 2"],
["tie", "player 2", "player 1", "tie"]
]
}}}
and depending on player 1's and player 2's "moves" ("move 1" and "move 2", respectively), determine the winner by indexing into the winner payoff matrix/list:
{{{
return winner[move_1 - 1][move_2 - 1]
}}}
The solution above is more "elegant" (using "smart data structures" and "dumb code" - using Fred Brooks's terminology above), compared to a "brute-force" solution using conditionals ("smart code" and "dumb data structures" a-la Brooks):
{{{
if move_1 == move_2:
return "tie"
if move_1 == 0 and move_2 == 1:
return "player 1"
if move_1 == 0 and move_2 == 2:
return "player 2"
if move_1 == 0 and move_2 == 3:
return "tie"
#... and so on, for ALL (!) possible conditions (7 or more, depending on how "efficiently" students code the "tie" condition :)
}}}
In this assignment, and for list-practicing purposes, I also ask the students to run the game multiple times and count the number of times each player wins, again, __not using conditionals__, but rather, using lists. This (somewhat 'forced' requirement, 'stretching' lists usage a bit :), should have the students produce data structures like:
{{{
win_counters = [0, 0, 0]
winner_index = ["tie", "player 1", "player 2"]
}}}
and simple ('dumb' a-la Brooks) code like:
{{{
win_counters[winner_index.index(winner)] += 1
}}}
Unfortunately, most students in this semester's class got the requirement for the first part (the winner payoff matrix) right, but the winner counters wrong, and produced the 'standard' conditionals solution, of the form ('dumb' data structures):
{{{
count_1 = 0 #only counts the wins of player 1
count_2 = 0 #only counts the wins of player 2
count_tie = 0 #only counts the ties
}}}
and the 'usual' (conditionals-based) code:
{{{
if winner == "player 1":
count_1 = count_1 + 1
if winner == "player 2":
count_2 = count_2 + 1
if winner == "tie":
count_tie = count_tie + 1
}}}
Now, the second part of the Data Structures unit, covers Dictionaries (another important and useful data structure). In this part I ask the students to convert their lists-based solution to the Morra game, into a dictionaries-based solution. From my experience, looking at the same problem and trying to solve it in different ways can generate deeper understandings and insights into effectiveness, efficiency, elegance, readability, expressiveness, and so on.
I won't go into the details of the dictionaries-based solution (it's not important to the point I want to make, //and// the students are still working on this assignment at the time of this writing ... :), but since most students had not completely coded their solution using lists, I could not give them a full 100% grade :(
One of my students, let's call her "Reena", came to me after she saw her 'non-perfect' grade (which she, justifiably, is not used to getting :), and told me that she doesn't understand why I deducted points, since she actually __did__ use a dictionaries-based solution, and therefore met the requirement of not using conditionals.
She proceeded to show me her code on her computer, and indeed, it used dictionaries and not conditionals.
I was really puzzled by it. I thought I had thoroughly reviewed her assignment (on my computer, after she turned in the link to her code), saw her conditionals-based solution, and therefore gave her the lower grade.
I don't claim to have a photographic memory (nor [[a bionic ear|I have a Bionic Ear]]), but I definitely experience "code smells", which are little unique and idiosyncratic ways people write code. And I remember __not__ being 'delighted' by Reena's solution (or the "code smell". I know, it sounds a bit weird, or new-agey, but I believe that seeing many (many, many, many) programs makes one sensitive and aware to programming idioms, templates, 'standard', awkward, expert, newbie, elegant, and crude/hacked ways of coding and solving problems).
So, I looked back at the link she had turned in to her program, and saw that I was right: the lists-based solution she had turned in had conditionals and __not__ dictionaries as her solution.
I became suspicious and very surprised And disappointed. Did Reena change her code after the fact because she could not live with a lower grade? I thought I had read her character well. She was a very solid, direct, straight-talking student, and this kind of behavior, had she really done it, did not fit my sense of her (another kind of "smell", this time of a person's character?)
I had to find out what happened. I emailed her and asked whether the link she had turned in for the lists-based assignment was hers. Her response was a big relief (and a renewed confidence in her honesty and character). She explained that she had already finished her dictionaries-based assignment, and turned it in as well, so when she got the grade and the feedback (on the ''lists-based solution'') saying she (and others) had to use non-conditionals for their solution, she immediately jumped and came to talk to me, since her ''dictionaries-based solution'' was indeed not using conditionals. In other words, she did not even refer to (remember?) her assignment with the lists and conditionals.
Mystery solved, confidence restored, character redeemed. Whew! (deep breath, good smell :)
----
^^1^^ As Niklaus Wirth (a "[[CS Sage|https://en.wikipedia.org/wiki/List_of_computer_scientists]]") said and wrote about: [[Algorithms + Data Structures = Programs|https://en.wikipedia.org/wiki/Algorithms_%2B_Data_Structures_%3D_Programs]]
<<list-links "[tag{!!title}]">>
I recently attended an evening of poetry reading by [[David Whyte|http://www.davidwhyte.com/]] at Stanford University, and was inspired by his insistence that it is critical for us as human beings to have ''real conversations'' with ourselves and with each other, and ask "real questions", that get at the heart of things, and for which we don't have ready-made and well-rehearsed answers. So who could express it better than Whyte himself (but, [[a different, but related take on questions|John O’Donohue - questions]] is given by [[John O'Donohue|https://www.johnodonohue.com/]], whom [[Whyte|http://www.davidwhyte.com/]] knew). >The marvelous thing about a good question is that it shapes our identity as much by the asking as it does by the answering. Nine years ago, I wrote a poem called "Sometimes" in which I talked about the "questions that can make or unmake a life ... questions that have no right to go away." >I still work with this idea. Questions that have no right to go away are those that have to do with the person we are about to become; they are conversations that will happen with or without our conscious participation. They almost always have something to do with how we might be more generous, more courageous, more present, more dedicated, and they also have something to do with timing: when we might step through the doorway into something bigger, better both beyond ourselves and yet more of ourselves at the same time. >If we are sincere in asking, the eventual answer will give us both a sense of coming home to something we already know as well a sense of surprise not unlike returning from a long journey to find an old friend sitting unexpectedly on the front step, as if she'd known, without ever being told, not only the exact time and date of your arrival but also your need to be welcomed back. !!!!And his 10 Questions That Have No Right to Go Away (referred to in his [[poem "Sometimes"|Sometimes - by David Whyte]]): * Do I know how to have real conversations? ** A real conversation always contains an invitation. You are inviting another person to reveal herself or himself to you, to tell you who they are or what they want. To do this requires vulnerability. Now we tend to think that vulnerability is associated with weakness, but there's a kind of robust vulnerability that can create a certain form of strength and presence too. * What can I be wholehearted about? ** So many of us aren't sure what we're meant to do. We wonder if we're simply doing what others are doing because we feel we don't have enough ideas or even enough strength of our own. What do I care most about in my vocation, in my family life, in my heart and mind? This is a conversation that we all must have with ourselves at every stage of our lives, a conversation that we so often don't want to have. We will get to it, we say, when the kids are grown, when there is enough money in the bank, when we are retired, perhaps when we are dead; it will be easier then. But we need to ask it now: What can I be wholehearted about now? * Am I harvesting from this year's season of life? **"Youth is wasted on the young" is the old saying. But it might also be said that midlife is wasted on those in their 50s and eldership is very often wasted on the old. Most people, I believe, are living four or five years behind the curve of their own transformation. I see it all the time, in my own life and others. The temptation is to stay in a place where we were previously comfortable, making it difficult to move to the frontier that we're actually on now. People usually only come to this frontier when they have had a terrible loss in their life or they've been fired or some other trauma breaks open their story. Then they can't tell that story any more. But having spent so much time away from what is real, they hit present reality with such impact that they break apart on contact with the true circumstance. So the trick is to catch up with the conversation and stay with it -- where am I now? -- and not let ourselves become abstracted from what is actually occurring around us. * Where is the temple of my adult aloneness? ** Gaston Bachelard, a French philosopher, said that one of the beautiful things about a home is that it is a place where you can dream about your future, and that a good home protects your dreams; it is a place where you feel sheltered enough to risk yourself in the world. * Can I be quiet even inside? ** All of our great traditions, religious, contemplative and artistic, say that you must a learn how to be alone and have a relationship with silence. It is difficult, but it can start with just the tiniest quiet moment. You may not want to confront it at first. But a long way down the road, when you inhabit a space fully, you no longer feel awkward and lonely. Silence turns, in effect, into its opposite, so it becomes not only a place to be alone but also a place that's an invitation to others to join you, to want to know who's there, in the quiet. * Am I too inflexible in my relationship to time? ** If you've got a wonderful memory of your childhood, it should live within you. If you've got a challenging relationship with a parent, that should be there as part of your identity now, both in your strengths and weaknesses. The way we anticipate the future forms our identity now. Time taken too literally can be a tyranny. We are never one thing; we are a conversation everything we have been, everything we are now and every possibility we could be in the future. * How can I know what I am actually saying? ** Poetry is often the art of overhearing yourself say things you didn't know you knew. It is a learned skill to force yourself to articulate your life, your present world or your possibilities for the future. We need that same skill as an art of survival. We need to overhear the tiny but very consequential things we say that reveal ourselves to ourselves. * How can I drink from the deep well of things as they are? ** To me, a well, a place where the water springs eternal all year round, is a very real, blessed place to stop and think. Almost always, when I'm struggling over a particular situation, I realize that I am only looking at the surface of the problem and refusing to go for the deeper dynamic that caused all the tension in the first place. All intimate relationships close friendships and good marriages are based on continued and mutual forgiveness. You will always trespass upon your friend's sensibilities at one time or another, or your spouse's. The only question is, Will you forgive the other person? And more importantly, Will you forgive yourself? We have to deepen our understanding, make ourselves more equal to circumstances, more easy with what we have been given or not given. We must drink from the deep well of things as they are. * Can I live a courageous life? ** The word "courage" comes from the old French word coeur meaning "heart." So "courage" is the measure of your heartfelt participation in the world. Human beings are constantly trying to take courageous paths in their lives: in their marriages, in their relationships, in their work and with themselves. But the human way is to hope that there's a way to take that courageous step without having one's heart broken. And it's my contention that there is no sincere path a human being can take without breaking his or her heart. There is no marriage, no matter how happy, that won't at times find you wanting and break your heart. In raising a family, there is no way to be a good mother or father without a child breaking that parental heart. In a good job, a good vocation, if we are sincere about our contribution, our work will always find us wanting at times. In an individual life, if we are sincere about examining our own integrity, we should, if we are really serious, at times, be existentially disappointed with ourselves. So it can be a lovely, merciful thing to think, "Actually, there is no path I can take without having my heart broken, so why not get on with it and stop wanting these extra-special circumstances which stop me from doing something courageous?" * Can I be the blessed saint that my future happiness will always remember? ** Here's the explanation for what sounds like a strange question. I have a poem called "Coleman's Bed" about a place in the West of Ireland where the Irish saint Coleman lived. The last line of that poem calls on the reader to remember "the quiet, robust and blessed saint that your future happiness will always remember." We go to places of pilgrimage where saints have lived, or even to Graceland, where Elvis lived, because these people gave something to the rest of us music or good works that has carried on down the years and that was a generous gift to the future. But that blessed saint could also be yourself the person who, in this moment, makes a decision that can make a bold path into the years to come and whom your future happiness will always remember. What could you do now for yourself or others that your future self would look back on and congratulate you for something it could view with real thankfulness because the decision you made opened up the life for which it is now eternally grateful?
Dealing with failure is easy: Work hard to improve. Success is also easy to handle: You've solved the wrong problem. Work hard to improve.
In his book When Things Start to Think, Neil Gershenfeld talks about some of the best practices they have at the Media Lab at MIT to promote and sustain creativity, learning and practical use (by industry). One of the principles they have is to maximize free flow and interaction between people, departments, disciplines, organizations, etc. Part of this best practice is the dealing with Intellectual Property (IP). What may seem like a dubious deal but turns out to be a win-win, is that every sponsor of the Lab relinquishes control of the invention/knowledge/IP gained by the Lab working on their problems, in return for being able to leverage/use any of the other sponsors' inventions/knowledge/IP. >The third trick that makes this work is the treatment of intellectual property, the patents and copyrights that result from research. Academia and industry both usually seek to control them to wring out the maximum revenue. But instead of giving one sponsor sole rights to the result of one project, our sponsors trade exclusivity for royalty-free rights to everything we do. This lets us and them work together without worrying about who owns what. >It's less of a sacrifice for us than it might sound, because very few inventions ever make much money from licensing intellectual property, but fights over intellectual property regularly make many people miserable. And it's less of a sacrifice for the sponsors than it might sound, because they leverage their investment in any one area with all of the other work going on. When they first arrive they re very concerned about protecting all of their secrets; once they notice that many of their secrets have preceded them and are already familiar to us, and that we can solve many of their internal problems, they relax and find that they get much more in return by being open.
In an article titled [[Design Process for a Non-majors Computing Course|http://andreaforte.net/GuzdialForteDesignProcess.pdf]], Mark Guzdial and Andrea Forte of Georgia Tech describe the design process/considerations for their intro course, based on the context of media (visual, audio) creation and manipulation. Here are their main points: * Course objectives: ** the goal is to prepare students to become software tool modifiers, not software tool developers ** the course should attract audiences/groups currently not engaged/interested in computing ** engage students in a relevant context ** provide opportunities for creativity ** make the learning experience social * Meeting the objectives ** The argument has been made that teaching programming, especially to non-majors, improves general problem-solving skills. Empirical studies of this claim have shown that we can’t reasonably expect an increase in general problem-solving skills after just a single course (about all that we might expect non-majors to take), but transfer of specific problem solving skills can happen. ** Media computation is relevant for these students because, for students not majoring in science or engineering, the computer is used more for communication than calculation. These students will spend their professional lives creating and modifying media. Since all media are becoming digital, and digital media are manipulated with software, programming is a communications skill for these students. ** Media computation is able to address the set learning objectives. Issues of data structuring and encoding arise naturally in media computation, e.g., sounds are typically arrays of samples, while pictures are matrices of pixel objects, each pixel containing red, green, and blue values. We were able to address the specifics of a CS1 course in the details of the course construction. * creativity was encouraged and required through expecting students to pick media and effects of their choosing * social engagement was present through student collaboration on, presentation, and sharing of artifacts and projects.
An article on KQED's ~MindShift website titled [[How to Trigger Students’ Inquiry Through Projects|http://ww2.kqed.org/mindshift/2013/07/15/how-to-trigger-students-inquiry-through-projects/]] based on a book titled //Thinking Through ~Project-Based Learning: Guiding Deeper Inquiry// by Jane Krauss and Suzie Boss, gives some sound advice and practical steps for designing good (triggering deep inquiry and learning) projects. It starts off with a good observation about tying learning objectives to activities and projects. You can start in a "top-down" fashion, beginning with learning objectives/standards and then map them to projects/activities, or "bottom-up", from ideas for projects/activities and map them to objectives/standards: >There are several ways to start designing projects. One is to select among learning objectives described in the curriculum and textbooks that guide your teaching and to plan learning experiences based on these. Another is to “back in” to the standards, starting with a compelling idea and then mapping it to objectives to ensure there is a fit with what students are expected to learn. The second method can be more generative, as any overarching and enduring concept is likely to support underlying objectives in the core subject matter and in associated disciplines, too. Either way you begin, the first step is to identify a project-worthy idea. In my experience, when you have mastery in a domain/subject, and a lot of experience and knowledge in that area, it is easier to start with ideas for "interesting projects", since you have a strong intuitive sense of why these projects are interesting, which in many cases boils down to them exploring/covering/exposing "important and big ideas" in that domain. In other words, these projects are "interesting" not just because they are "relevant" to the students but also because they reveal fundamental and important principles and concepts. This makes it easy (or at least straight forward) to map to learning objectives and standards. !!!Steps in designing good projects * Step 1 - Identify Project-worthy Concepts. If you start "top-down" you will consider standards, objectives, and concepts, which are significant and rich, as high potential candidates for covering in a project. Identify four or five BIG, important, significant concepts for each subject. * Step 2 - Explore Their Significance and Relevance. It is important to probe these standards/objectives/concepts, to "justify" their value and priority. >>Think: Why do these topics or concepts matter? What should students remember about this topic in 5 years? For a lifetime? Think beyond school and ask: In what ways are they important and enduring? What is their relevance in different people’s lives? In different parts of the world? Explore each concept, rejecting and adding ideas until you arrive at a short list of meaningful topics. * Step 3 - Find Real-Life Contexts. This is the important step of linking the ideas to relevant and meaningful contexts, since this will me a strong motivator in engaging students. >>Look back to three or four concepts you explored and think about real-life contexts. Who engages in these topics? Who are the people for whom these topics are central to their work? See if you can list five to seven professions for each concept. * Step 4 - Engage Critical Thinking. You should think of ways to trigger critical thinking activities as part of the project. Some examples of student activities are: **Compare and contrast **Predict **Make a well-founded judgment or informed decision **Understand causal relationships (cause and effect) **Determine how parts relate to the whole (systems) **Identify patterns or trends **Examine perspectives and alternate points of view **Extrapolate to create something new **Evaluate reliability of sources *Step 5 - Write a Project Sketch. This should include an overview and a description of scenarios and activities, making it clear what and how students will learn during this project. * Step 6 - Plan the Setup. Here you should define 3 elements: ** the project title - a short, memorable one is best ** the starting/entry event (the "hook" for the project) - an event, news item, video clip, etc. ** the driving question for your project. This would be >>a research question students will feel compelled to investigate. Imagine a driving question that leads to more questions, which, in their answering, contribute to greater understanding. Good questions grab student interest (they are provocative, intriguing, or urgent), are open ended (you can’t Google your way to an answer), and connect to key learning goals. * Step 7 - Workshop your project idea. >>Colleagues, students, parents, and subject matter experts will ask questions that will clarify your thinking and contribute ideas you might not have considered.
In the book [[Nature's Numbers|https://cismasemanuel.files.wordpress.com/2010/02/ian-stewart-numerele-naturii.pdf]] Ian Stewart succinctly states a common experience we have: ''Determinism and predictability are not synonymous.'' And gives examples of where we experience it in real life all the time. Stewart pithily observes: > It's not so much a universe in which -- as Albert Einstein memorably refused to believe^^1, 2^^ -- God plays dice: it seems more a universe in which dice play God. A "clean and simple" example from the world of math, can be seen in Cellular Automata, for example [[Rule 30 (in Stephen Wolfram's classification)|http://mathworld.wolfram.com/Rule30.html]]: <a href="./resources/CA rule 30.png" target="new"><img src="./resources/CA rule 30.png" width="100%" height="100%" /></a> As Wolfram indicates: > Rule 30 is of special interest because it is chaotic ([[Wolfram 2002, p. 871|http://www.wolframscience.com/nksonline/page-871c-text]]), with central column given by 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, ... . In fact, this rule is used as the random number generator used for large integers in the Wolfram Language. Interpreting the central column as binary numbers and taking successive bits gives the sequence of numbers 1, 3, 6, 13, 27, 55, 110, 220, 441, 883, 1766, ... . The members of this sequence that are prime are 3, 13, 883, 237051898781, ... . One implication of CA 30 is that you cannot calculate or formulate the behavior (or a specific result/output) of rule 30 using a function/formula (i.e., you cannot predict). You actually have to go through all the steps in the algorithm (i.e., it is deterministic). The equivalent from life is that (often? very often?) there are cases where you cannot plan/predict what will happen; you just have to live the experience (go through it; "execute life"; just run it :) ---- ^^1^^ - Vasant Natarajan writes an excellent analysis/review about [[What Einstein meant when he said “God does not play dice ...”|https://arxiv.org/ftp/arxiv/papers/1301/1301.1656.pdf]], where he concludes: >There were thus three features of Quantum Mechanics that Einstein disapproved of -- it was probabilistic, nonlocal, and linear. Despite this opposition, Einstein realized that it was a successful theory within its domain of applicability. He believed that a future unified field theory would have to reproduce the results of Quantum Mechanics, perhaps as a linear approximation to a deeper nonlinear theory. This was similar to how the relativistic gravitational field of General Relativity (with a finite propagation speed of the gravitational force) led to Newton’s law of gravitation (with its action-at-a-distance force) in the nonrelativistic limit. But Einstein was convinced that Quantum Mechanics was not the correct approach to deducing the fundamental laws of physics. ^^2^^ This is what [[Stephen Hawking|http://www.hawking.org.uk/about-stephen.html]] has to say about [[the predictability of the universe|http://www.hawking.org.uk/does-god-play-dice.html]], in light of black holes (ha!): >To sum up, what I have been talking about, is whether the universe evolves in an arbitrary way, or whether it is deterministic. The classical view, [[put forward by Laplace|The deterministic Universe - per Pierre Simon Laplace]], was that the future motion of particles was completely determined, if one knew their positions and speeds at one time. This view had to be modified, when Heisenberg put forward his Uncertainty Principle^^3^^, which said that one could not know both the position, and the speed, accurately. However, it was still possible to predict one combination of position and speed. But even this limited predictability disappeared, when the effects of black holes were taken into account. The loss of particles and information down black holes meant that the particles that came out were random. One could calculate probabilities, but one could not make any definite predictions. Thus, the future of the universe is not completely determined by the laws of science, and its present state, as Laplace thought. God still has a few tricks up his sleeve. ^^3^^ A principle which even (the personification of) [[DEATH|http://www.chrisjoneswriting.com/death.html]] in Terry Pratchett's novels is [[trying to believe in|THE UNCERTAINTY PRINICIPLE - according to Sir Terry]].
In her book [["Incompleteness: The Proof and Paradox of Kurt Godel"|https://www.ams.org/notices/200604/rev-kennedy.pdf]], Rebecca Goldstein writes: >Einstein sometimes speaks of objective reality as the "out yonder": >>Out yonder there was this huge world, which exists independently of us human beings and which stands before us like a great, eternal riddle, at least partially accessible to our inspection and thinking. The contemplation of this world beckoned like a liberation. And Goldstein summarizes ''about Einstein'': >This is an eloquent statement of Einstein's credo as a scientist, and it really could not be more at odds with the sentiments of almost all the other prominent physicists of his circle. >Einstein understood the business of physics to be to discover theories that offer a glimpse of the objective nature that stands "out yonder" behind our experiences. Werner Heisenberg, together with such men as the Danish Niels Bohr and the German Max Born (who are together the leading advocates of the Copenhagen interpretation of quantum mechanics) reject this view in the name of an intellectual movement known as "positivism," according to which any attempt to reach out beyond our experience results in arrant nonsense. And about ''Gödel'' (Godel, Goedel): >Gödel, like Einstein, is committed to the possibility of reaching out, pace the positivists, beyond our experiences to describe the world "out yonder." Only since Godel's field is mathematics, the "out yonder" in which he is interested is the domain of abstract reality. His commitment to the objective existence of mathematical reality is the view known as conceptual, or mathematical, realism. It is also known as mathematical Platonism, in honor of the ancient Greek philosopher whose own metaphysics was a vehement rejection of the Sophist Protagoras' "man is the measure of all things." Edwin Jaynes [[writes about the philosophical worldview differences between Einstein and Bohr|Clearing up physical mysteries with probability]], illuminating other aspects as well.
An excellent CS book, focusing on computational thinking and not on language features. From the introduction: >In my view, an introductory computer science course should strive to accomplish three things. > * First, it should demonstrate to students how computing has become a powerful mode of inquiry, and a vehicle of discovery, in a wide variety of disciplines. This orientation is also inviting to students of the natural and social sciences, who increasingly benefit from an introduction to computational thinking, beyond the limited “black box” recipes often found in manuals. > * Second, the course should engage students in computational problem solving, and lead them to discover the power of abstraction, efficiency, and data organization in the design of their solutions. > * Third, the course should teach students how to implement their solutions as computer programs. In learning how to program, students more deeply learn the core principles, and experience the thrill of seeing their solutions come to life. >Unlike most introductory computer science textbooks, which are organized around programming language constructs, I deliberately lead with interdisciplinary problems and techniques. This orientation is more interesting to a more diverse audience, and more accurately reflects the role of programming in problem solving and discovery. A computational discovery does not, of course, originate in a programming language feature in search of an application. Rather, it starts with a compelling problem which is modeled and solved algorithmically, by leveraging abstraction and prior experience with similar problems. Only then is the solution implemented as a program. And [[a quote I often refer to|Computer Science is no more about computers than astronomy is about telescopes.]] myself, in a slightly different form: >We need to do away with the myth that computer science is about computers. Computer science is no more about computers than astronomy is about telescopes, biology is about microscopes or chemistry is about beakers and test tubes. Science is not about tools, it is about how we use them and what we find out when we do. ::-- Michael R. Fellows and Ian Parberry, Computing Research News (1993)
In a delightful (in its "radicalism" or at least "divergent" thinking :) article titled [["Computer Criticism vs. Technocentric Thinking"|http://worrydream.com/refs/Papert%20-%20Computer%20Criticism%20vs.%20Technocentric%20Thinking.pdf]] by Seymour Papert, he defines "Computer Criticism" (part of his paper's title): >I am proposing a genre of writing one could call "computer criticism" by analogy with such disciplines as literary criticism and social criticism. The name does not imply that such writing would condemn computers any more than literary criticism condemns literature or social criticism condemns society. The purpose of computer criticism is not to condemn but to understand, to explicate, to place in perspective. Of course, understanding does not exclude harsh (perhaps even captious) judgment. The result of understanding may well be to debunk. But critical judgment may also open our eyes to previously unnoticed virtue. And in the end, the critical and the creative processes need each other. He also writes (in 1970(!), and echoing Alan Kay's opinion that [[The Real Computer Revolution Has Not Happened Yet]]) that critics of Computing say that >[computing will never] have the stature of Shakespeare or the depth and complexity of social structure. I think history will gainsay this attitude. The computer is a medium of human expression and if it has not yet had its Shakespeares, its Michelangelos or its Einsteins, it will. Besides, the complexity and subtlety of the computer presence already make it a challenging topic for critical analysis. We have scarcely begun to grasp its human and social implications. * On "technocentrism": >Technocentrism refers to the tendency to give a similar centrality to a technical object -- for example computers or [programming/coding]. This tendency shows up in questions like "what is //the// effect of //the// computer on cognitive development?" or "does [programming] work? [i.e., "does it "deliver"?]" * And the implications of such questions (and what some researchers, therefore, do): >such turns of phrase [see above] often betray a tendency to think of "computers" and of "programming" as agents that act directly on thinking and learning; they betray a tendency to reduce what are really the most important components of educational situations -- people and cultures -- to a secondary, facilitating role. The context for human development is always a culture, never an isolated technology. In the presence of computers, cultures might change and with them people's ways of learning and thinking. But if you want to understand (or influence) the change, you have to center your attention on the culture -- not on the computer. One can see this technocentric approach and the resulting controlled experiments in papers like [["Learning to code or coding to learn? A systematic review"|https://www.researchgate.net/publication/328246560_Learning_to_code_or_coding_to_learn_A_systematic_review]] by Shahira Popat, Louise Starkey (producing a meta-study of 10 "technocentric" studies). * about computing and programming as a "material" or "ingredient" for changing culture, or significant things you are doing in the context of a culture: >[we should be looking at] using the computer not as a "thing in itself " that may or may not deliver benefits, but as a material that can be appropriated to do better whatever you are doing (and which will not do anything if you are not!) * About the appropriateness of a strictly controlled experimentation environment, when trying to measure the effect of programming on students: >It is a self-defeating parody of scientism to suppose that one could keep everything else, including the culture, constant while adding a serious computer presence to a learning environment. If the role of the computer is so slight that the rest can be kept constant, it will also be too slight for much to come of it. The "treatment" methodology leads to a danger that all experiments with computers and learning will be seen as failures: either they are trivial because very little happened, or they are "unscientific" because something real did happen and too many factors changed at once. * about looking at the impact of learning to program from the "demand side" (the what and how effects are tested): > [some experimenters] are checking for an improvement in a very, narrow and specific form of planning activity, so they use a focused ad hoc test. > [while other experimenters] approach the problem with a relatively open mind about what the cognitive effects [of computing] might be: they apply a broad spectrum of well-known, standard tests of cognitive function (amongst many others: divergence, reflectivity-impulsivity, operational competence, right-left orientation, matching familiar figures, and following directions.) * and from the "supply side" (what kind of "programming education" is given to the students): >the children are to be given "programming"-- and the purpose of the experiments is to see what happens. But there is no such thing as "programming-in-general." These children are not given "programming." They are given [Scratch or Python, or Java, etc.]. But there is no such thing as "Scratch/Python/Java-in-general" either. The children encounter [Computing, programming, projects, teachers, subjects] in [very] particular way[s, all of which determine what they are really getting!]. * Papert claims (and I agree :) that these technocentric experiments don't provide a good picture and conclusions because they suffer from >inadequate recognition of the fact that what they are looking at, and therefore making discoveries about, is not programming but cultures that happen to have in common the presence of a computer and the [particular programming] language.
Donald Ervin Knuth (born January 10, 1938) is a computer scientist and Professor Emeritus of the Art of Computer Programming at Stanford University.
In the article [[Bend Sinister|https://monoskop.org/images/1/14/Goriunova_Olga_ed_Fun_and_Software_Exploring_Pleasure_Paradox_and_Pain_in_Computing.pdf]] by artist and programmer [[Simon Yuill|http://www.lipparosa.org/]], he mentions:
Knuth describes the act of writing programs as like teaching somebody else to do a task. The programmer teaches the machine. The machine, however, also teaches the programmer through the way it enforces greater precision on the ‘tutor’ than a purely human teaching scenario might require.
[[Donald Knuth|http://en.wikipedia.org/wiki/Donald_Knuth]]
<<list-links "[tag{!!title}]">>
"""
Douglas Noel Adams was an English writer, humourist and dramatist. He is best known as the author of The Hitchhiker's Guide to the Galaxy, which started life in 1978 as a BBC radio comedy.
Born: March 11, 1952, Cambridge
Died: May 11, 2001, Santa Barbara
"""
<<list-links "[tag{!!title}]">>
[[Douglas Richard Hofstadter|https://en.wikipedia.org/wiki/Douglas_Hofstadter]] (born February 15, 1945) is an American academic whose research focuses on consciousness, analogy-making, artistic creation, literary translation, and discovery in mathematics and physics. He is best known for his book Gödel, Escher, Bach: an Eternal Golden Braid, first published in 1979, for which he was awarded the 1980 Pulitzer Prize for general non-fiction. Hofstadter was born in New York, New York, the son of Nobel Prize-winning physicist Robert Hofstadter. He grew up on the campus of Stanford University, where his father was a professor, and he attended the International School of Geneva in 1958-1959. He graduated with Distinction in Mathematics from Stanford University ([[where I also graduated from|http://ldtprojects.stanford.edu/~hmark/]]) in 1965. Douglas Hofstadter's books on mind, consciousness, and computers/computing are very inspirational. [img[Hoftstadter Meta - from xkcd|resources/Hofstadter Meta.png]] He loves ambigrams, but he's [[not the only one|Ambigrams by Scott Kim]] :-)
A few excerpts from the [[excellent article about Hofstadter in the Atlantic Magazine|http://www.theatlantic.com/magazine/archive/2013/11/the-man-who-would-teach-machines-to-think/309529/]]
* [The] operating premise (of Hofstadter and his students at Indiana University] is simple: the mind is a very unusual piece of software, and the best way to understand how a piece of software works is to write it yourself. Computers are flexible enough to model the strange evolved convolutions of our thought, and yet responsive only to precise instructions. So if the endeavor succeeds, it will be a double victory: we will finally come to know the exact mechanics of our selves—and we’ll have made intelligent machines.
* In 1931, the Austrian-born logician Kurt Gödel had famously shown how a mathematical system could make statements not just about numbers but about the system itself. Consciousness, Hofstadter wanted to say, emerged via just the same kind of “level-crossing feedback loop.” (see [[The world's shortest explanation of Gödel's theorem]])
* In GEB [his 1980 Book //Gödel, Escher, Bach//], Hofstadter was calling for an approach to AI concerned less with solving human problems intelligently than with understanding human intelligence - at precisely the moment that such an approach, having borne so little fruit, was being abandoned.
* Hofstadter wanted to ask: Why conquer a task if there’s no insight to be had from the victory? “Okay,” he says, “Deep Blue plays very good chess - so what? Does that tell you something about how we play chess? No. Does it tell you about how Kasparov envisions, understands a chessboard?” A brand of AI that didn’t try to answer such questions - however impressive it might have been - was, in Hofstadter’s mind, a diversion.
* “To me, as a fledgling AI person,” he says, “it was self-evident that I did not want to get involved in that trickery. It was obvious: I don’t want to be involved in passing off some fancy program’s behavior for intelligence when I know that it has nothing to do with intelligence. And I don’t know why more people aren’t that way.”
* “The quest for ‘artificial flight’ succeeded when the Wright brothers and others stopped imitating birds and started … learning about aerodynamics,” Stuart Russell and Peter Norvig write in their leading textbook, [[Artificial Intelligence: A Modern Approach|http://aima.cs.berkeley.edu/]]. AI started working when it ditched humans as a model, because it ditched them. That’s the thrust of the analogy: Airplanes don’t flap their wings; why should computers think?
* [The above point is] a compelling point. But it loses some bite when you consider what we want: a Google that knows, in the way a human would know, what you really mean when you search for something. Russell, a computer-science professor at Berkeley, said to me, “What’s the combined market cap of all of the search companies on the Web? It’s probably four hundred, five hundred billion dollars. Engines that could actually extract all that information and understand it would be worth 10 times as much.”
* Perhaps, as Russell and Norvig politely acknowledge in the last chapter of their textbook, in taking its practical turn, AI has become too much like the man who tries to get to the moon by climbing a tree: “One can report steady progress, all the way to the top of the tree.”
* “At every moment,” Hofstadter writes in Surfaces and Essences, his latest book (written with Emmanuel Sander), “we are simultaneously faced with an indefinite number of overlapping and intermingling situations.” It is our job, as organisms that want to live, to make sense of that chaos. We do it by having the right concepts come to mind. This happens automatically, all the time. Analogy is Hofstadter’s go-to word. The thesis of his new book, which features a mélange of A’s on its cover, is that analogy is “the fuel and fire of thinking,” the bread and butter of our daily mental lives.
* “Look at your conversations,” he says. “You’ll see over and over again, to your surprise, that this is the process of analogy-making.” Someone says something, which reminds you of something else; you say something, which reminds the other person of something else—that’s a conversation. It couldn’t be more straightforward. But at each step, Hofstadter argues, there’s an analogy, a mental leap so stunningly complex that it’s a computational miracle: somehow your brain is able to strip any remark of the irrelevant surface details and extract its gist, its “skeletal essence,” and retrieve, from your own repertoire of ideas and experiences, the story or remark that best relates.
* when everybody else in AI started building products, he and his team, as his friend, the philosopher [[and Edgie, Daniel Dennett|https://www.edge.org/memberbio/daniel_c_dennett]], wrote, “patiently, systematically, brilliantly,” way out of the light of day, chipped away at the real problem. “Very few people are interested in how human intelligence works,” Hofstadter says. “That’s what we’re interested in—what is thinking?—and we don’t lose track of that question.”
* In this he [Hofstadter] is the modern-day William James, whose blend of articulate introspection (he introduced the idea of the stream of consciousness) and crisp explanations made his 1890 text, Principles of Psychology, a classic. “The mass of our thinking vanishes for ever, beyond hope of recovery,” James wrote, “and psychology only gathers up a few of the crumbs that fall from the feast.”
* When you read Fluid Concepts and Creative Analogies: Computer Models of the Fundamental Mechanisms of Thought, which describes in detail this architecture and the logic and mechanics of the programs that use it, you wonder whether maybe Hofstadter got famous for the wrong book.
* On the one hand, the software we know how to write is very orderly; most computer programs are organized like a well-run army, with layers of commanders, each layer passing instructions down to the next, and routines that call subroutines that call subroutines. On the other hand, the software we want to write would be adaptable - and for that, a hierarchy of rules seems like just the wrong idea. Hofstadter once summarized the situation by writing, “The entire effort of artificial intelligence is essentially a fight against computers’ rigidity.”
* It is no coincidence that AI saw a resurgence in the ’90s, and no coincidence either that Google, the world’s biggest Web company, is “the world’s biggest AI system,” in the words of Peter Norvig, a director of research there, who wrote [[AI: A Modern Approach|http://aima.cs.berkeley.edu/]] with Stuart Russell. Modern AI, Norvig has said, is about “data, data, data,” and Google has more data than anyone else.
* Josh Estelle, a software engineer on Google Translate, which is based on the same principles as Candide and is now the world’s leading machine-translation system, explains, “you can take one of those simple machine-learning algorithms that you learned about in the first few weeks of an AI class, an algorithm that academia has given up on, that’s not seen as useful - but when you go from 10,000 training examples to 10 billion training examples, it all starts to work. Data trumps everything.”
* You don’t have to push Google Translate very far to see the compromises its developers have made for coverage, and speed, and ease of engineering. Although Google Translate captures, in its way, the products of human intelligence, it isn’t intelligent itself. It’s like an enormous Rosetta Stone, the calcified hieroglyphics of minds once at work.
* [Dave Ferrucci, who led the Watson team at IBM] is not blind to the difference [between Artificial Intelligence and Human Intelligence]. He likes to tell crowds that whereas Watson played using a room’s worth of processors and 20 tons of air-conditioning equipment, its opponents relied on a machine that fits in a shoebox and can run for hours on a tuna sandwich. A machine, no less, that would allow them to get up when the match was over, have a conversation, enjoy a bagel, argue, dance, think - while Watson would be left humming, hot and dumb and un-alive, answering questions about presidents and potent potables.
* The question that Hofstadter wants to ask Ferrucci, and everybody else in mainstream AI, is this: Then why don’t you come study it ("Real Artificial Intelligence", working on understanding thinking]?
** “I have mixed feelings about this,” Ferrucci told me when I put the question to him last year. “There’s a limited number of things you can do as an individual, and I think when you dedicate your life to something, you’ve got to ask yourself the question: To what end? And I think at some point I asked myself that question, and what it came out to was, I’m fascinated by how the human mind works, it would be fantastic to understand cognition, I love to read books on it, I love to get a grip on it” - he called Hofstadter’s work inspiring - “but where am I going to go with it? Really what I want to do is build computer systems that do something. And I don’t think the short path to that is theories of cognition.”
** Peter Norvig, one of Google’s directors of research, echoes Ferrucci almost exactly. “I thought he was tackling a really hard problem,” he told me about Hofstadter’s work. “And I guess I wanted to do an easier problem.”
* Stuart Russell, Norvig’s co-author of [[AI: A Modern Approach|http://aima.cs.berkeley.edu/]], goes further. “A lot of the stuff going on is not very ambitious,” he told me. “In machine learning, one of the big steps that happened in the mid-’80s was to say, ‘Look, here’s some real data—can I get my program to predict accurately on parts of the data that I haven’t yet provided to it?’ What you see now in machine learning is that people see that as the only task.”
* It’s insidious, the way your own success can stifle you. As our machines get faster and ingest more data, we allow ourselves to be dumber. Instead of wrestling with our hardest problems in earnest, we can just plug in billions of examples of them.
* It seems unlikely that feeding Google Translate 1 trillion documents, instead of 10 billion, will suddenly enable it to work at the level of a human translator. The same goes for search, or image recognition, or question-answering, or planning or reading or writing or design, or any other problem for which you would rather have a human’s intelligence than a machine’s.
*This is a fact of which Norvig, just like everybody else in commercial AI, seems to be aware, if not dimly afraid. “We could draw this curve: as we gain more data, how much better does our system get?” he says. “And the answer is, it’s still improving—but we are getting to the point where we get less benefit than we did in the past.”
* For James Marshall, a former graduate student of Hofstadter’s, it’s simple: “In the end, the hard road is the only one that’s going to lead you all the way.”
* Hofstadter strikes me as difficult, in a quiet way. He is kind, but he doesn’t do the thing that easy conversationalists do, that well-liked teachers do, which is to take the best of what you’ve said - to work you into their thinking as an indispensable ally, as though their point ultimately depends on your contribution.
----
Relevant to (missed?) opportunities in CS: [[Victor Bret|http://worrydream.com/#!/Bio]] has a [[video presentation (~33 min.) on "The Future of Programming",|https://www.youtube.com/watch?v=8pTEmbeENF4]] which is partially a tongue-in-cheek view (the slide projector, the pocket protector, the "dated" remarks, 'guesses', and 'opinions') of where we missed opportunities in the evolution of programming.
One idiomatic practice in Python that often surprises people coming from programming languages where exceptions are considered, well, exceptional, is [[EAFP|https://docs.python.org/3.5/glossary.html#term-eafp]]: “it’s easier to ask for forgiveness than permission”. Quickly, EAFP means that you should just do what you expect to work and if an exception might be thrown from the operation then catch it and deal with that fact. What people are traditionally used to is [[LBYL|https://docs.python.org/3.5/glossary.html#term-lbyl]]: “look before you leap”. Compared to EAFP, LBYL is when you first check whether something will succeed and only proceed if you know it will work.
In his excellent book [[Probably Approximately Correct|http://www.probablyapproximatelycorrect.com/]], Leslie Valiant writes about his work in defining and using what he calls ecorithms, to address the way to improve computer/software performance (and knowledge) through learning and evolutionary changes. One of the main reasons he started working in this area is his realization (following Alan Turing's and John von Neumann's) that math, logic , and "classic" (traditional) computation have their limitations when it comes to dealing with all the complexities of the real world (he tells the [[funny story about von Neumann|If you think math is difficult ...]]). In the book, Valiant talks about theoryful vs. theoryless analysis and behavior: > Much of everyday human decision making appears to be of a similar ["theoryless"] nature -- it is based on a competent ability to predict from past observations without any good articulation of how the prediction is made or any claim of fundamental understanding of the phenomenon in question. The predictions need not be perfect or the best possible. They need merely be useful enough. In this regard he quotes Arthur Eddington (in 1933), in what I think is an attempt to show the prevalent scientific sentiment, which is still strong today, too: > I hope it will not shock experimental physicists too much if I say that we do not accept their observations unless they are confirmed by theory. Valiant describes ecorithms: > Understanding ecorithms requires developments beyond basic algorithmic theory. One now needs to analyze not only the algorithm itself but also the algorithm's relationship with its environment. > The theory of probably approximately correct, or PAC, learning, deals with this relationship between the algorithm and its environment. It addresses the fundamental question of how a limited entity can cope in a world that in comparison is limitless, and does so while keeping to an absolute minimum any assumptions about that limitless world. !!! On the Mechanistic Explanations of Nature >What Crick and Watson had done was to discover the physical substrate on which heritable information is represented, much like silicon is the physical substrate of present-day computers. For both substrates it is impressive how the exacting requirements imposed on them can be achieved with as much miniaturization and economy as they are. However, no one would say that the secret of computers is in the silicon, since computers can be equally well realized in many other physical substrates, though perhaps not quite so economically at present. Indeed, one reason that computer development has been as rapid as it has is that computer scientists made a conceptual separation at the very beginning. between the physical technology in which the computer was implement: and the algorithmic content of what was being executed on the machines This enabled hardware, software, and algorithms to evolve independently and at their own spectacular rates. > >Making similar headway in our study of biology, whether evolutionary of cognitive, demands the same separation of algorithm and substrate. The distinction made here between a physical object and the information processing it performs is self-evident for anyone dealing with computers. The distinction is in no way subtle. Even for a traffic light one can easily distinguish between its symbolic function and its physical construction. But perhaps these distinctions were not quite so obvious in former times. The mind–body problem of Descartes and his followers may have been an earlier reference to such a distinction. But now when computers are ubiquitous there is no reason for confusing ‘what it does” and “what does it." !!! The Learnable - How can one draw general lessons from particular experiences? >The idea that biological and cognitive processes should be viewed as computations appeared almost immediately upon the discovery of universal computation, and it was discussed by the early pioneers, including Turing and von Neumann. Because of subsequent slow progress in making this connection concrete or useful, some have despaired that it can never be made into more than metaphor, and that for fundamental reasons it cannot be made into a science. I disagree. I believe that developing any new science is fraught with challenges, and that we are making progress in this area at about the pace that might be reasonable to expect. > >The universality of computation is what justifies this approach to cognition. Some have complained that the favored metaphor for the brain in every age has been the most complicated mechanism known at the time. Since the computer is currently that most complex mechanism, is it not a fallacy to adopt that metaphor? I would argue that the computer analogy goes beyond the fact that the computer is another complicated mechanism. > >What makes it different this time is the widely agreed universality of computation over all processes that we regard as mechanistic. >While computers are extremely good at reasoning using mathematical logic, they find common sense much more challenging. We are faced with two issues as a result: identifying what it is about common sense that logic fails to capture, and whether there is a scientific road to the problem of common sense. The first issue, I argue, is a result of mathematical logic requiring a theoryful world in which to function well. Common sense corresponds to a capability of making good predictive decisions in the realm of the theoryless. To address the second issue we need therefore a theory of the general nature of the theoryless. As I shall argue, the road we must take in that direction is paved with ecorithms. The algorithms studied most widely in computer science aim to solve instances of some specific problem, such as integer multiplication of the Traveling Salesman Problem. These algorithms, by design, already incorporate the expertise needed for solving them. Ecorithms are also algorithms but they have an important additional nature. They use generic learning techniques to acquire knowledge from their environment so that they can perform effectively in the environment from which they have learned. They achieve this effectiveness not by intensive design, but by making use of knowledge they have learned. The designed-in expertise is limited to generic learning capabilities and their use. Understanding ecorithms requires developments beyond basic algorithmic theory. One now needs to analyze not only the algorithm itself but also the algorithm's relationship with its environment. > >There is a difficulty in placing generalization at the core of learning, at Last for philosophers, who have argued for millennia that it is difficult to make a logical argument for rationally inferring anything from one situation to another that one has never before experienced. This is known as the problem of induction. Aristotle said that there are two forms of argument, syllogistic and inductive.” Here I interpret these words to mean that if one has a certain belief, then the belief was arrived at either by logical deduction syllogism) from things already believed, or by induction (generalization) from particular experiences. In this formulation it is induction that is the more basic since it enables primary beliefs, whereas logical deduction requires some previous beliefs. The main paradox of induction is the apparent contradiction between the following two of its facets. On the one hand, if no assumptions are made about the world, then clearly induction cannot be justified, because the World could conceivably be adversarial enough to ensure that the future is exactly the opposite of whatever prediction has just been made. > >[...] On the other hand, and in apparent contradiction to this argument, successful induction abounds all around us. Generation after generation, millions of children learn everyday concepts, such as dogs and cats, chairs and tables, after seeing examples of them, rather than precise definition. >There may exist some acceptable assumptions that hold for the reproducible, naturally occurring form of induction, and under which induction is rigorously justifiable. Valiant argues that there are just two such assumptions, which are sufficient, necessary, and unavoidable. * One is the Invariance Assumption: the context in which the generalization is to be applied cannot be fundamentally different from that in which it was made. * The second is the Learnable Regularity Assumption. We are quite good, but possibly not perfect at categorizing... We must be doing it by applying some criteria...which can be viewed as regularities in the world. These regularities should be detectable, and validated by practical (in terms of time, attention, and other cognitive/processing resources) feasibility tests/calculations/processing. Valiant draws some parallels between a teacher and a programmer: * at a high level we can think of a teacher as a programmer who is defining a sequence of concepts to be learned in a certain order, and perhaps in no other way. The reason is, that in order to learn a new concept, we/humans need to be "ready" and aware of and familiar with "prerequisite concepts" (e.g. if you don't know what the concept "data" means, you can not learn and know what "big data" is. Same with "black swan"). * a big difference between a programmer and a teacher is that a programmer needs to know exactly what is the state of the program and what it does. A teacher does not know exactly what the learner knows or how s/he interprets each word (and even the learner does not necessarily know exactly what their "state" is). This teacher-learner incomplete knowledge is inevitable and has both positive and negative aspects. One of the positives is a certain robustness/resiliency in the face of errors, as well as the potential and ability to recover and/or improve learning over time. * both a teacher and a programmer should point out the next good thing to learn, as well as provide examples (both positive and negative) and label them. * every learner has certain learning algorithms and a good teacher (and a good programmer) will therefore come up with a good set and sequence of labeled examples which will accelerate and improve learning of concepts and relationships. >In practice we can never be certain that the world will not change on us in an unexpected way, so that future examples will be from a very different distribution from those in the past. Past performance is not necessarily indicative of future results. Living organisms, however, need to make decisions all the time and take a view on what will happen next. The only course available is to learn as many of the world's regularities as we can, and allow them to guide our decision making. There is simply no alternative. !!! Need We Fear Artificial Intelligence? Valiant concludes the book with the following hopeful and calming/level-headed thoughts: >There may be some good news for humans in the fact that one can be intelligent in many different ways. It gives us hope that we may endow robots with intelligence superior to ours but only in directions that are useful and not threatening to us. Also, it makes it clear that there is no good reason to want to make robots that are exactly like humans. >The most singular capability of living organisms on Earth must be that of survival. Anything that survives for billions of years, and many millions of generations, must be good at it. Fortunately, there is no reason for us to endow robots with this same capability. Even if their intelligence becomes superior to ours in a wide range of measures, there is no reason to believe that they would deploy this in the interests of their survival over ours unless we go out of our way to make them do just that. > We have limited fear of domesticated animals. We do not necessarily have to fear intelligent robots either. They will not resist being switched off, unless we provide them with the same heritage of extreme survival training that our own ancestors had been subject to on Earth. <html> <table> <tr> <td width="25%" height="100%"> <a href="./resources/escher_hands.jpg" target="new"><img src="./resources/escher_hands.jpg" /></a> </td> <td width="25%" height="100%"> <a href="./resources/escher_ascend.jpg" target="new"><img src="./resources/human_robot_hand.jpg" width="70%" height="70%"/></a> </td> </tr> </table> </html>
Edsger Wybe Dijkstra (May 11, 1930 August 6, 2002) was a Dutch computer scientist. He received the 1972 Turing Award for fundamental contributions to developing programming languages, and was the Schlumberger Centennial Chair of Computer Sciences at The University of Texas at Austin from 1984 until 2000.
<<list-links "[tag{!!title}]">>
<br>
`To teach is to learn twice.`
: -- Joseph Joubert
"""
"""
`The business of life is to learn, not to know.`
: -- Jonathan Rosen
"""
"""
`The larger the island of knowledge, the longer the shoreline of wonder.`
: -- Ralph Sockman
"""
"""
`I'd take the awe of understanding over the awe of ignorance any day.`
: -- Douglas Adams (from //The Salmon of Doubt//)
"""
"""
`We make, not just to have, but to know.`
: -- Alan Kay
"""
"""
`Understanding — like civilization, happiness, music, science and a host of other great endeavors — is not a state of being, but a manner of traveling. And the main goal of helping children learn is to find ways to show them that great road which has no final destination, and that manner of traveling in which the journey itself is the reward.`
: -- Alan Kay in [[Powerful Ideas Need Love Too|http://worrydream.com/refs/Kay%20-%20Powerful%20Ideas%20Need%20Love%20Too.html]]
"""
"""
`Good teachers possess a capacity for connectedness. They are able to weave a complex web of connections among themselves, their subjects, and their students so that students can learn to weave a world for themselves.`
: ― Parker J. Palmer (in //The Courage to Teach: Exploring the Inner Landscape of a Teacher's Life//)
"""
"""
<html>
<a href="./resources/xkcd_teaching.png" target="new"><img src="./resources/xkcd_teaching_s1.png" /></a><br>from xkcd
</html>
<<list-links "[tag[education-item]]">>
"""
"""
<html>
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-nc-sa/3.0/us/88x31.png" /></a><br />To the extent possible and under my control, this work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/">Creative Commons Attribution-NonCommercial-ShareAlike 3.0 United States License</a>.
</html>
From an [[excellent, uplifting and down-to-earth talk|http://www.pbs.org/johngardner/chapters/3.html]] by John Gardner on Education and Excellence. >We don't even know what skills may be needed in the years ahead. That is why we must train our young people in the fundamental fields of knowledge, and equip them to understand and cope with change. That is why we must give them the critical qualities of mind and durable qualities of character that will serve them in circumstances we cannot now even predict. and >If the man in the street says, 'Those fellows at the top have to be good, but I'm just a slob and can act like one' -- then our days of greatness are behind us. We must foster a conception of excellence that may be applied to every degree of ability and to every socially acceptable activity. A missile may blow up on its launching pad because the designer was incompetent or because the mechanic who adjusted the last valve was incompetent. The same is true of everything else in our society. We need excellent physicists and excellent mechanics, excellent cabinet members and excellent first-grade teachers. The tone of our society depends upon a pervasive an almost universal striving for good performance. > >And we are not going to get that kind of striving, that kind of alert and proud attention to performance, unless we can instruct the whole society in a conception of excellence that leaves room for everybody who is willing to strive -- a conception of excellence which means that whoever I am or whatever I am doing, provided that I am engaged in socially acceptable activity, some kind of excellence is in my reach. And >Exploration of the full range of our own potentialities is not something that we can safely leave to the chances of life. It is something to be pursued avidly to the end of our days. We should look forward to an endless and unpredictable dialogue between our own potentialities and the claims of life -- not only the claims we encounter, but the claims we invent. And by potentialities I mean not just skills, but the full range of our capacities for sensing, wondering, learning, understanding, loving, and aspiring... > >A society whose maturing consists simply of acquiring more firmly established ways of doing things is headed for the graveyard -- even if it learns to do these things with greater and greater skill. In the ever-renewing society what matures is a system or framework within which continuous innovation, renewal and rebirth can occur. > >Our thinking about growth and decay is dominated by the image of a single life-span, animal or vegetable. Seedling, full flower, and death...But for an ever-renewing society, the appropriate image is a total garden, a balanced aquarium or other ecological system. Some things are being born, other things are flourishing, still other things are dying -- but the system lives on.
Education is what, when, and why to do things. Training is how to do it. In science, if you know what you are doing, you should not be doing it. In engineering, if you do not know what you are doing, you should not be doing it. : -- from [[Richard Hamming]]: The Art of Doing Science and Engineering (1997)
|Technology Name | Domain/Subject | Technology Reference URL | Usage Examples | My Usage | Comments |h |[[GeoGebra|http://www.geogebra.org/cms/]] | Math | [[Intro to GeoGebra [pdf]|http://www.geogebratube.org/material/show/id/7382]] | [[examples|http://www.geogebratube.org/?lang=en]] | [[examples|http://employees.org/~hmark/math/index.html#geogebra]] |Powerful, [[Mathematica|http://www.wolfram.com/mathematica/]]-, [[Sage|http://sagemath.org/]]-, or [[Maple|http://www.maplesoft.com/]]-like Math package; free| |[[NetLogo|http://ccl.northwestern.edu/netlogo/]] | CS, Science | [[manuals|http://ccl.northwestern.edu/netlogo/docs/]] | [[examples library|http://ccl.northwestern.edu/netlogo/models/index.cgi]] | [[examples|http://employees.org/~hmark/math/index.html#netlogo]] |Excellent low-entry, high ceiling free software; generates Java applets| |[[LightBot|http://www.kongregate.com/games/Coolio_Niato/light-bot]] | CS | [[Download swf|http://playtomic.com/games/511-lightbot20.swf?source=feed]] | [[Helene Martin: Teaching with LightBot|http://www.helenemartin.com/2011-08-teaching-with-lightbot/]] | [[programming|http://employees.org/~hmark/math/lightbot.html ]] |Programming a virtual robot | |[[LogicSim|http://www.tetzl.de/java_logic_simulator.html]] | Engineering/CS/Math | | [[Short Tutorial|http://www.tetzl.de/java_logic_simulator.html]] | [[examples|http://employees.org/~hmark/math/index.html#logicsim]] |Designing binary logic circuits | |[[Easy Java Simulation (EJS)|http://www.um.es/fem/EjsWiki/pmwiki.php]] | Math, Physics | | [[Open Source Physics|http://www.compadre.org/osp/index.cfm]] | [[examples|http://employees.org/~hmark/math/index.html#ejs]] |Powerful simulation package, with ODE support. Produces Java applets| |[[Tracker video analysis|http://www.compadre.org/osp/items/detail.cfm?ID=7365]] | Physics, Math | [[Lab/user manual|http://www.compadre.org/osp/document/ServeFile.cfm?ID=12037&DocID=2924&Attachment=1]] | [[Samples & Download|http://www.cabrillo.edu/~dbrown/tracker/]] | [[example|Tracker video analysis - falling bodies]] |Quantitative video analysis; free; multiple platforms| |[[Sage|http://sagemath.org/]] | Math | [[documentation|http://www.sagemath.org/help.html#SageStandardDoc]] | [[worksheets|https://sagenb.kaist.ac.kr:8066/pub/]] | [[examples|http://employees.org/~hmark/math/index.html#sage]] |Powerful, [[Mathematica|http://www.wolfram.com/mathematica/]]- or [[Maple|http://www.maplesoft.com/]]-like Math package; free; Python scriptable| |[[Scratch|http://scratch.mit.edu/]] | CS, other | | | [[examples|http://scratch.mit.edu/projects/myh9090/1871961]] |Drag-and-drop, snap-on programming. Scratch 2.0 is web(Flash)-enabled| |[[Snap|http://snap.berkeley.edu/]] | CS, other | [[manual|http://snap.berkeley.edu/SnapManual.pdf]] | | |Drag-and-drop, snap-on programming. Extended implementation of Scratch; web(javascript)-enabled| |[[AppInventor|http://appinventor.mit.edu/]] | CS | [[source code|http://code.google.com/p/app-inventor-releases/]] | [[samples|http://www.appinventorblocks.com/]] | |[[Scratch|http://scratch.mit.edu/]]-like snapping tiles; Android app [[IDE|http://en.wikipedia.org/wiki/Integrated_development_environment]] | |[[Blockly|http://code.google.com/p/blockly/]] | CS, other | | | |[[Scratch|http://scratch.mit.edu/]]-like snapping tiles for "visual programming" | |[[Stencyl|http://www.stencyl.com/]] | CS, game programming, Physics | [[Overview|http://www.stencyl.com/stencyl/overview/#section1]] | | |[[Scratch|http://scratch.mit.edu/]]-like, web-enables, Flash and Mobile support | |[[Soulver|http://www.acqualia.com/soulver/]] | Math | [[enhancement|http://worrydream.com/ScrubbingCalculator/]] | | |"Smart" notebook+spreadsheet, combined with embedded math calculations abilities | |[[Greenfoot|http://www.greenfoot.org/door]] | CS (Java) | | | |For learning & teaching Java; [[BlueJ|http://www.bluej.org/]] is a compatible IDE | |[[Algodoo|http://www.algodoo.com/wiki/Home]] | Physics | | [[examples|http://www.algodoo.com/algobox/]] | |2D simulation; not free; [[free, older version: Phun|http://www.algodoo.com/wiki/Download]]| |[[Physion|http://physion.net/]] | Physics, CS | | [[examples|http://physion.net/en/scenes]] | |2D simulation; free; not webbrowser playable; Javascript programmable| |[[Gamestar Mechanic|http://gamestarmechanic.com/]] | CS, Game Design | | [[Getting Started|https://sites.google.com/a/elinemedia.com/gsmlearningguide/]] | |Game playing, game design; free; web browser enabled| |[[Sodaplay|http://soda.co.uk/categories/sodaplay]] | CS, Game Design, Physics | | [[Launching tools/suite|http://sodaplay.com/create]] | |Game playing, game design; free; web browser enabled suite: Creator, Moovl, Newtoon, Race| |[[Perlenspiel|http://www.perlenspiel.org/]] | CS, Game Design | | [[Examples by Brian Moriatry|http://users.wpi.edu/~bmoriarty/ps/examples.html]] | [[my comments|Teaching game design]] |Game playing, game design; free; web browser enabled; some similarities to [[NetLogo|http://ccl.northwestern.edu/netlogo/]]| |[[VPython|http://vpython.org/index.html]] | CS, Physics, Visualization | [[documentation|http://vpython.org/contents/doc.html]] | [[examples|http://www.youtube.com/vpythonvideos]] | |Programming + 3D visualization in Python; free; can be 'web-enabled' with [[GlowScript|http://vpython.org/contents/doc.html]]| |[[Go|http://golang.org/]] | CS | [[documentation|http://golang.org/doc/]] | | |An open source programming environment by Google. Supported and can be hosted on Google's [[App Engine|https://developers.google.com/appengine/]] | |[[Alice|http://www.alice.org/index.php]] | CS | [[documentation|http://www.alice.org/index.php?page=3.1/download_materials]] | | [[education-related papers|http://www.alice.org/index.php?page=publications/publications]] |An open source environment for 3D (game) programming based on Java | |[[Kojo|http://www.kogics.net/kojo]] | CS, Math, Art, Music | [[documentation|http://wiki.kogics.net/sf:kojo-docs]] | [[examples|http://www.kogics.net/codeexchange]] | [[education-related comments|http://wiki.kogics.net/sf:kalpana-center]] |An open source programming environment both downloadable and web-enabled (based on the [[Scala programming language|http://www.scala-lang.org/]]) | CS = Computer Science IDE = Integrated Development Environment ODE = Ordinary Differential Equations
The math professor (UC Berkeley) Edward Frenkel wants to expose learners to the Beauty of Math (reminds me of [[Brian Harvey, Dan Garcia and team|https://bjc.berkeley.edu/team/leadership/]] and their [["Beauty and Joy of Computing"|https://bjc.berkeley.edu/]] effort (also at UC Berkeley)). When [[asked|http://www.slate.com/articles/health_and_science/new_scientist/2013/10/edward_frenkel_on_love_and_math_what_is_it_like_to_be_a_mathematician.html]] about the way we teach math to students, Frenkel has a vivid image/analogy: >The way mathematics is taught is akin to an art class in which students are only taught how to paint a fence and are never shown the paintings of the great masters. When, later on in life, the subject of mathematics comes up, most people wave their hands and say, "Oh no, I don't want to hear about this, I was so bad at math." What they are really saying is, "I was bad at painting the fence." :: [img[painting the fence vs. the painting of the masters|resources/paint fence and masters paintings small.png]] In [[another article|http://www.slate.com/articles/health_and_science/science/2013/04/e_o_wilson_is_wrong_about_math_and_science.html]], Frenkel blasts the scientist E. O. Wilson, who seems to suggest to science students that math is not essential to science, and says: >If mathematics were fine art, then Wilson’s view of it would be that it’s all about painting a fence in your backyard. Why learn how to do it yourself when you can hire someone to do it for you? But fine art isn’t a painted fence, it’s the paintings of the great masters. And likewise, mathematics is not about “number-crunching,” as Wilson’s article suggests. It’s about concepts and ideas that empower us to describe reality and figure out how the world really works. Galileo famously said, “The laws of Nature are written in the language of mathematics.” Mathematics represents objective knowledge, which allows us to break free of dogmas and prejudices. It is through math that we learned Earth isn’t flat and that it revolves around the sun, that our universe is curved, expanding, full of dark energy, and quite possibly has more than three spatial dimensions. But since we can’t really imagine curved spaces of dimension greater than two, how can we even begin a conversation about the universe without using the language of math? I think that the truth is somewhere on both sides: math can and does enrich both the human experience (as [[Richard Feynman had also said|Richard Feynman on the beauty and simplicity of nature]]), and enables deep scientific insights, but it is not (necessarily) a necessary, nor a sufficient condition (and Albert Einstein is a famous example of a scientist with great imagination and insight, who, [[it is claimed|https://www.theguardian.com/uk/2006/may/22/science.research]], needed some help with his math to "solidify" his theories :) . And on a similar note, [[Wilson also mentions|https://www.wsj.com/articles/SB10001424127887323611604578398943650327184]] that "Newton invented calculus in order to give substance to his imagination.". On this last point (help with math) [[Wilson (rightfully) claims|https://www.wsj.com/articles/SB10001424127887323611604578398943650327184]] that collaboration between scientists and mathematicians may be very fruitful, and that scientists may have help readily available, if/when needed: >It is far easier for scientists to acquire needed collaboration from mathematicians and statisticians than it is for mathematicians and statisticians to find scientists able to make use of their equations.
In a lecture at Stanford University by Professor of Mathematics Brian Conrad, titled //Rubik, Escher, Bank$//, he used a good and simplified analogy to explain a bit of the role of elliptic curves in Public Key Encryption schemes used by banks, credit card companies and other financial institutions. For a step-by-step worked out [[example of another encryption algorithm (RSA)|RSA encryption example - simplified]], see the [ext[NetLogo simulation/model|math/netlogo/RSAcrypto.html]] I've created. (In the same lecture Conrad used another analogy to explain a bit of what's going on in [[Escher's Print Gallery]]) The analogy Conrad used was to explain the main concepts behind public key encryption and the role of elliptic functions. He was trying to answer the common question of "how come two parties/people who want to exchange secret messages can publish (to the whole world) what's called "public keys" which __must__ be used in order to decipher the secret messages, but only the party/person who has another key called a "private key" can decipher them? He basically tried to simplify the [[Diffie-Hellman key exchange process|http://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange]]. So, as an example which __does not use elliptic functions__, but rather a method which __can be hacked/broken__ (i.e. it's not secure and does NOT safeguard encrypted messages), Conrad used an analogy, employing [[power functions (exponentiation)|http://en.wikipedia.org/wiki/Exponentiation]]. Let's assume that party A wants to encrypt a message and send it to party B. For simplification's sake let's also assume that the unencrypted message is "12" (and it can be generalized to any message). * First, the two parties need to agree on a "base number", which they can do publicly, since it is only a "seed" from which the encryption keys will be developed. Let's say that they agree on a base/seed of 2. * Then, party A needs to select a (secret) "private key" known only to party A, let's say it chooses the number 3. Party A then creates a (non-secret) "public key", using the seed (2) and private key (3). In our "toy" scenario (making this a non-secure method), let's assume that the way to create the public key is to take the base and raise it to the power of the secret key. So 2^^3^^ = 8, which party A publishes to the world. * Similarly, party B needs to select a (secret) "private key" too, known only to party B, say, the number 4. Party B also creates a (non-secret) "public key", using the same method and gets 2^^4^^ = 16, which it publishes to the world. * Now, party A has party B's (published) public key and therefore can calculate a "shared secret" key by using its own private key, and party B's public key: 16^^3^^ = 4096 (but notice that (2^^4^^)^^3^^ = 4096). * Party B does the same thing with its own secret key and party A's public key and gets the same "shared key" (and that's the whole point!): 8^^4^^ = 4096 (but notice that (2^^3^^)^^4^^ = 4096) So, by publicly agreeing on a seed number (2) and using a calculation (which in our "toy" example is exponentiation, which is non-secure, since it can easily be reversed with a logarithm, but is not easily reversed with elliptic functions), party A and party B exchanges and poses a "shared secret" code, and can now start encrypting messages to each other, without any listening parties being able to decrypt them. As an example, party A can encrypt the message (12) using the shared secret key (4096) and multiplication, and get an encrypted message of 12 * 4096 = 49152 (the result) which is sent to party B (and which the whole world can see). Now, the simplified and fallacious part of this example is that since we are using exponentiation to encrypt the secret message, and since there is a __reverse function__ to exponentiation, namely __logarithms__, this method is not safe for encryption. But, elliptic functions don't have easily reversible functions, and that's why they are good for encrypting. But let's continue with this example. Party B (and the rest of the world for that matter) gets the encrypted message (49152 standing for the original message "12"), and using the "shared secret" key (4096), which no one else has, can decrypt the transmission (49152 / 4096) and get the original message (12).
I recently came across an article in the New York Times Opinion page by Neal Gabler who is a senior fellow at the Annenberg Norman Lear Center at the University of Southern California, titled [[The Elusive Big Idea|http://www.nytimes.com/2011/08/14/opinion/sunday/the-elusive-big-idea.html?pagewanted=all&_r=1&]].
The funny thing is that even though one of the main points of this article is that we live in a "post-ideas" world, where according to Gabler no big ideas are being generated anymore ("Post-idea refers to thinking that is no longer done"), this in itself is kind of a "big idea" - or at least it's implications (if true) are BIG!
Another point Gabler is making is that we live in an age where we have less (no?) big thinkers:
>If our ideas seem smaller nowadays, it's not because we are dumber than our forebears but because we just don't care as much about ideas as they did. In effect, we are living in an increasingly post-idea world a world in which big, thought-provoking ideas that can t instantly be monetized are of so little intrinsic value that fewer people are generating them and fewer outlets are disseminating them, the Internet notwithstanding. Bold ideas are almost passe.
I think that in saying this, Gabler is falling into the trap he himself is describing, namely, that the information inundation we are experiencing makes us "myopic" (my term). It seems that he is making this kind of assertion, //because// he is "drowning" in information, and is looking in the wrong places. One could argue that Gabler falling into this trap doesn't "make it so" for everyone, and isn't necessarily "the sign of the times".
I agree with the writer that there is a REAL DANGER that in the "information age" we currently live in, we may drown in information and be sidetracked by the chaff and lured away from the grain (or in the writer's words: "if information was once grist for ideas, over the last decade it has become competition for them"). BUT, in my mind, this is truly an example of a danger/challenge that brings with it a __tremendous__ opportunity.
The situation the writer describes, where "[w]e are inundated with so much information that we wouldn't have time to process it even if we wanted to, and most of us don't want to" is an opportunity (or a call for "upgrading our survival capabilities"!) to develop new skills and abilities for filtering, analyzing, digesting, incorporating and creating new information, knowledge and ideas.
If instead of looking at the wealth of information as a "tidal wave" which will drown us, we look at it as "truckloads and trainloads of potential Lego blocks^^1^^" for us to build with, then the "threatening situation" can turns into "the largest construction site ever". But again, we need to develop new skills and capabilities, and maybe even revisit and reinforce our value systems, so as to prioritize the effort required to generate new ideas from the wealth of information, and so as to value and use the results in beneficial ways, without falling into the trap of "We prefer knowing to thinking because knowing has more immediate value. It keeps us in the loop, keeps us connected to our friends and our cohort. Ideas are too airy, too impractical, too much work for too little reward."
As far as taking on the challenge, one interesting and possibly enjoyable (and definitely educational and creative) way to deal with this "information inundation" is "information curation", where we become curators, or we use curators to help us pick the grain from the chaff. [[Maria Popova|http://www.brainpickings.org/index.php/about/]] gives an [[interesting BBC interview|http://www.bbc.co.uk/news/technology-20415707]] about the nature of curation and curators^^2^^:
>It [curation] brings to the forefront that which is interesting, meaningful, and stimulating and memorable.
>...
>A great curator, to me, is someone who takes such bits of information and transmutes them into useful knowledge. It's someone who shines a spotlight on the timeless corners of the "common record", the ones that are perhaps obscured from view, or forgotten, or poorly understood, making them timely again by contextualising them and linking them to ideas and issues of present urgency, correlating and interpreting.
[[In the same interview|http://www.bbc.co.uk/news/technology-20415707]] Popova states her belief about curation and computers^^3^^:
>It's this transmutation of information into practical wisdom about how the world works, and moral wisdom about how the world ought to work that sets the human apart from the algorithm - and from the computer.
>It offers, I believe, the only real hope of making use and making sense of humanity's collective knowledge.
An example of an inspiring site where [[big ideas are definitely alive and well|http://edge.org/conversations]], contradicting the claim of the NY Times writer, is edge.org, for example, where the goal of the creator John Brockman, in his own words is
>To arrive at the edge of the world's knowledge, seek out the most complex and sophisticated minds, put them in a room together, and have them ask each other the questions they are asking themselves.
which he does very successfully, in my opinion!
The [[man behind edge.org, John Brockman|http://edge.org/memberbio/john_brockman]] is himself a "fountain of big ideas" and the books he has been editing (like [[What Have You Changed Your Mind About?]], "This will make you smarter", [[Is the Internet Changing the Way You Think?]] and [[others|http://edge.org/conversation/books-from-edge]] are full of big thinkers expressing big ideas.
So the bottom line for me is:
* I'm very glad to be living in an age where we have such easy access to so much information
* Learning how to deal with the vast amounts of information is definitely a worthwhile effort, and it'll be exciting to find and develop the ways, skills, and capabilities to do that (for example, by developing better [[Computational Thinking/Literacy|A Framework for Computational Thinking, Computational Literacy]] skills.)
* [[Education and technology|A Framework for Computational Thinking, Computational Literacy]]^^4^^ can be our powerful allies on this journey of discovery and betterment
----
^^1^^ - [[a metaphor borrowed|http://www.brainpickings.org/index.php/2011/08/01/networked-knowledge-combinatorial-creativity/]] from [[Maria Popova|http://www.BrainPickings.org]]
^^2^^ - see [[What We Talk About When We Talk About Curation |http://www.brainpickings.org/index.php/2012/03/16/percolate-curation/]] by Popova.
And also [[Farnam Street|https://fs.blog]], an excellent blog, from which I can quote from [[a book review|https://fs.blog/2014/03/contagious-6-reasons-things-catch-on/]] about a book written by [[Maria Konnikova|https://www.mariakonnikova.com/]], who writes:
>Content should have an ethical appeal, an emotional appeal, or a logical appeal. A rhetorician strong on all three was likely to leave behind a persuaded audience. Replace rhetorician with online content creator, and Aristotle’s insights seem entirely modern. Ethics, emotion, logic—it’s credible and worthy, it appeals to me, it makes sense.
^^3^^ - I'm a bit skeptical about the impossibility of automating/computerizing (at least some) creative processes. It reminds me a bit of the [[chess playing claims|The end of an era, the beginning of another? HAL, Deep Blue and Kasparov]] that "computers will never be able to 'think' in a creative way and beat humans in the game of chess". Or the historical fact that before Google's search engine technology, Yahoo actually started as a [[Yahoo Directory|http://en.wikipedia.org/wiki/Yahoo!_Directory]] service, based on large numbers of human searchers/indexers to //manually// create searchable index/directory pages.
^^4^^ - The effort to automate/computerize chess playing and the fact that the solution was __not__ to "teach the computer" to play like a Grand Master, taught us something about human creativity and thought (and [[how different they are from machine performance|History of the chess table]]). I believe that the efforts to automate curation (despite Popova's doubts) will teach us something about creativity, curation, innovation, which is an exciting frontier!
A long time ago (maybe 30 years^^1^^) I had discovered [[emacs|https://www.gnu.org/software/emacs/index.html#features]] and was hooked. Who can resist the (nerdy) charms/pull of "An extensible, customizable, free/libre text editor — and more"^^3^^? And there is definitely "more"^^2^^. As they say, ''emacs has everything but the kitchen sink''. So you can imagine how delighted I was to find some sort of validation to the saying, in, of all places, a school bathroom. I know the spelling is different and it's not a kitchen sink, //but//, now the saying can be extended (ha!) to say ''emacs is everything under the sink'' :) <a href="./resources/eemax_2.jpg" target="new"><img src="./resources/eemax_2.jpg" width="50%" height="20%" /></a> """ """ ---- ^^1^^ - For those curious about Emacs history: Emacs was originally implemented in 1976 on the MIT AI Lab's Incompatible Timesharing System (ITS), as a collection of TECO macros. The name “Emacs” was originally chosen as an abbreviation of “Editor MACroS”. This version of Emacs, GNU Emacs, was originally written in 1984. ^^2^^ - emacs is more than a "customizable text editor"! [[A longer list is pretty long|https://www.emacswiki.org/#toc5]], but it is an entire ecosystem of functionality beyond text editing, including a project planner, mail and news reader, debugger interface, calendar, an [[AI development environment|https://www.emacswiki.org/emacs/CategoryArtificialIntelligence]], various calculators, many games, a web browser, a [[PIM|https://www.emacswiki.org/emacs/CategoryPersonalInformationManager]], databases, and (yes!) more... ^^3^^ - I don't want to start (or continue) a religious and/or political "war" but an employee of mine once bought me a ~T-Shirt with the following printing. Of course there’s also a different version of the shirt where the words emacs and vi are reversed (including the name of the little boy :), but that’s the whole point -- some people use vi and others use emacs. [>img[we use emacs|./resources/use_emacs.png][./resources/use_emacs_1.png]]
Bret Victor is a thought-provoking and talented thinker and doer (as in designing and building software tools). I've been following [[some of his work|http://worrydream.com/]], and found quite a few of my ideas about thinking, learning, doing, programming similar to his, but sometimes significantly expanded and well-developed.
I was surprised (well, maybe not, come to think of it ;-), or at least pleased, that in [[an excellent video/demo|http://vimeo.com/67076984]], Bret mentioned the exact same [[quote by Richard Hamming|Perhaps there are thoughts we cannot think]], which I referred to when writing about Hamming's paper [[On why Math works for us|On why Math works for us]].
Hamming's quote makes the point that due to evolution, and similarly to the natural limits of our senses (limited visible spectrum, audible frequency range, odors we can smell), "perhaps there are thoughts we cannot think".
Victor takes this and points out that, humans are overcoming some of the limitations of our senses and build tools to expand and go beyond them. From that, he draws the analogy that we can and should also build tools that expand our thinking capabilities, and enable us to think (currently) unthinkable thoughts^^1^^. And he gives a couple of examples of tools that aided new thoughts and new ways of thinking, such as writing (which "made thoughts visible"), mathematical notation (the power of which [[I wrote about here|The power of a new literacy]]), and computer user interfaces (allowing us to expose and manipulate things brought out in the interface).
In my mind, this is a very clear and inspiring call and motivation to develop methodologies and tools for teaching and learning [[Computational Thinking|A Framework for Computational Thinking, Computational Literacy]].
Victor quotes [[Carver Mead|http://en.wikipedia.org/wiki/Carver_Mead]] from ~CalTech:
>Right now, today, we can't see the thing, at all, that's going to be the most important 100 years from now.
echoing a similar observation about education: we teach and prepare our students today for jobs (and a world) we have no idea about.
And he adds:
>We cannot see the thing. At all. But whatever that thing is -- people will have to think it. And we can, right now, today, prepare powerful ways of thinking for these people. We can build the tools that make it possible to think that thing.
>We cannot see the thing. At all. My job is to make sure our children can.
In order to allow us to enable thinking unthinkable thoughts, Victor proposes leveraging some definitions borrowed from Jerome Bruner and Jean Piaget, about modes of thinking: Enactive, Iconic, and Symbolic. Or in current user interface terminology:
* ''Interactive'' - thinking by manipulating and exploring with your body, etc.,
* ''Visual'' - thinking by being able to see, visually compare and contrast, transform and abstract, etc., and
* ''Symbolic'' - thinking by manipulating language, symbols, logic, procedures/algorithms, etc.
Teaching and learning in ways that simultaneously engage learners in __all__ of the above ways, using tools that enable all these channels, is very powerful, because it leads learners to develop not just stronger understanding, but also ''strong intuitions'' about the learned concepts and their relationships.
[[George Polya|http://en.wikipedia.org/wiki/George_P%C3%B3lya]] (of [["How to Solve it"|https://notendur.hi.is/hei2/teaching/Polya_HowToSolveIt.pdf]] fame), has a lot to say about intuition, conjectures, guessing, and plausible reasoning, in the introduction to his book [[Induction And Analogy In Mathematics|https://archive.org/download/Induction_And_Analogy_In_Mathematics_1_/Induction_And_Analogy_In_Mathematics_1_.pdf]]:
>Strictly speaking, all our knowledge outside mathematics and demonstrative logic (which is, in fact, a branch of mathematics) consists of conjectures.
>[...]We secure our mathematical knowledge by demonstrative reasoning, but we support our conjectures by plausible reasoning, A mathematical proof is demonstrative reasoning, but the inductive evidence of the physicist, the circumstantial evidence of the lawyer, the documentary evidence of the historian, and the statistical evidence of the economist belong to plausible reasoning.
>[...]Demonstrative reasoning is safe, beyond controversy, and final. Plausible reasoning is hazardous, controversial, and provisional. Demonstrative reasoning penetrates the sciences just as far as mathematics does, but it is in itself (as mathematics is in itself) incapable of yielding essentially new knowledge about the world around us. __Anything new that we learn about the world involves plausible reasoning__ (my emphasis), which is the only kind of reasoning for which we care in everyday affairs.
>[...]Certainly, let us learn proving, but also __let us learn guessing__ (my emphasis). This sounds a little paradoxical and I must emphasize a few points to avoid possible misunderstandings.
>Mathematics is regarded as a demonstrative science. Yet this is only one of its aspects. Finished mathematics presented in a finished form appears as purely demonstrative, consisting of proofs only. Yet mathematics in the making resembles any other human knowledge in the making. You have to guess a mathematical theorem before you prove it; you have to guess the idea of the proof before you carry through the details. You have to combine observations and follow analogies; you have to try and try again. The result of the mathematician's creative work is demonstrative reasoning, a proof; but the proof is discovered by plausible reasoning, by guessing. If the learning of mathematics reflects to any degree the invention of mathematics, it must have a place for guessing, for plausible inference.
>There are two kinds of reasoning, as we said: demonstrative reasoning and plausible reasoning. Let me observe that they do not contradict each other; on the contrary, they complete each other. In strict reasoning the principal thing is to distinguish a proof from a guess, a valid demonstration from an invalid attempt. In plausible reasoning the principal thing is to distinguish a guess from a guess, a more reasonable guess from a less reasonable guess.
So, as Polya says, learning how to guess well is essential (actually, he says it's the __only__ way to generate new knowledge!). My strong conviction (and Victor's too ;-) is that good tools can develop intuitions and strengthen the art/skill of "fruitful guessing" - in other words "trigger/enable thinking unthinkable thoughts".
It's interesting [[to note|Encouraging Math discoveries]] that [[Francis Edward Su|http://www.math.hmc.edu/~su/]] is echoing similar sentiments in his article [ext[TEACHING RESEARCH: ENCOURAGING DISCOVERIES|resources/Francis Edward Su - encouraging discoveries in Math.pdf]], [[quoting Henri Poincare|Encouraging Math discoveries]].
Back to Victor. He gives a series of compelling examples of ways to enable (or at least trigger) starting to think in new ways about things ("thinking unthinkable thoughts"). He states that tools to enable this should have certain capabilities:
* The state, behavior, and evolution of systems and phenomena needs to be made visible and explicit (Victor's example of [[annotating scientific papers|http://worrydream.com/#!/ScientificCommunicationAsSequentialArt]])
* Systems and Models in their entirety, and all of their variables need to be exposed for interactions
* Multiple views, representations, and perspectives need to be available and enabled for comparisons and manipulations (Victor's example of [[a digital filter|http://worrydream.com/#!/ExplorableExplanations]])
* Both the __structure__ of systems and models, as well as their __dynamic behavior and data__ should be manipulatable and open to meaningful interaction (Victor's example of [[a visualization and animation environment/tool|http://worrydream.com/#!/DrawingDynamicVisualizationsTalkAddendum]])
----
^^1^^ it is an interesting question of whether there is a limit to the thoughts we will ever be able to think, or as [[Haldane|https://en.wikipedia.org/wiki/J._B._S._Haldane]] said: [[My own suspicion is that the universe is not only queerer than we suppose, but queerer than we can suppose... I suspect that there are more things in heaven and earth that are dreamed of, or can be dreamed of, in any philosophy.]]
In an article ([ext[TEACHING RESEARCH: ENCOURAGING DISCOVERIES|resources/Francis Edward Su - encouraging discoveries in Math.pdf]]) describing [[Francis Edward Su|http://www.math.hmc.edu/~su/]]'s math-teaching experience (of middle schoolers), he quotes Henri Poincare: >The principal aim of mathematical education is to develop certain faculties of the mind, and among these intuition is not the least precious. It is through it that the mathematical world remains in touch with the real world. But Poincare also said: >It is by logic that we prove, but by intuition that we discover. which reflects similar sentiments by George Polya (on about intuition, conjectures, guessing, and plausible reasoning) expressed in his book [ext[Induction And Analogy In Mathematics|https://archive.org/download/Induction_And_Analogy_In_Mathematics_1_/Induction_And_Analogy_In_Mathematics_1_.pdf]]. Anyway, when Su started teaching (he's currently teaching Math at Harvey Mudd College) he was wondering: >How does one turn a learner into a discoverer? When I was starting out as a new professor, I might have given these answers (see list below). >... Now, I shall explain why I believe every one of these pieces of advice is either plainly wrong or, at best, inadequate. And he lists the lessons he learned along the way, questioning his original answers. * Lesson #1. Teach the needed background? ** No. Nurture the yawp.^^1^^ (see Su's [[FunFacts site|http://www.math.hmc.edu/funfacts/]] at Harvey Mudd College) * Lesson #2. Cultivate maturity in your students? ** No. Revive their child-like curiosity and imagination. * Lesson #3. Identify invisible yawpers.^^1^^ * Lesson #4. Inspire them? ** Better: create spaces for self-inspiration. (see [[the Moore method for teaching Math|http://legacyrlmoore.org/reference/quick_start-3.pdf]]) * Lesson #5. Ask good questions? ** Better: teach how to ask good questions (since, as John O'Donohue had said: [[questions are like lanterns|John O’Donohue - questions]]) . * Lesson #6. Give open problems? ** Better: give open-ended problems. * Lesson #7. Select the smartest students? ** Not necessarily; select motivated students! (see similarity^^2^^ to Neil Gershenfeld at the MIT Media Lab) * Lesson #8. Advertise the thrill of research? ** Better: set complete expectations. (i.e. research can be fun and exciting, but also frustrating at times) * Lesson #9. Be an expert in what you advise? ** No, let the student be the expert. (the teacher as a "co-adventurer") * Lesson #10. Encourage independence? ** No! Give close guidance, and build community. (at least in the early stages of study and research) """ """ ------------------------- ^^1^^ YAWP - A mathematical yawp is that expression of surprise or delight at discovering the beauty of a mathematical idea or argument (a yawp is a loud cry or yell. But in the poetry of Walt Whitman, the word yawp refers to the inner groaning inside each of us, too deep for words, that is waiting to be released and experienced. If a yawp is the thrill of discovery, a poem is a yawp that is communicated well.) ^^2^^ From [ext[WHEN THINGS START TO THINK|resources/WHEN THINGS START TO THINK - Chapter 13 - Information and Education.pdf]] I found that one of the best predictors of a student’s success working this way was their grades; I make sure that they have a few F’s. Students with perfect grades almost always don’t work out, because it means they’ve spent their time trying to meticulously follow classroom instructions that are absent in the rest of the world. Students with both A’s and F’s have a much better record, because they’re able to do good work and also set priorities for themselves. They’re the ones most able to pose — and solve — problems that go far beyond anything I might assign to them.
We have all seen/experienced it: you want to install software on your device, but before you can do that, you have to go through some (very dense) legalese and click "I Agree", or else you don't get to install the software. !!!!First, on the serious side of the issue (and it is serious!): An official definition (from [[TechTarget|http://searchcio.techtarget.com/definition/End-User-License-Agreement]]): >An end user license agreement (EULA) is a legal contract between a software developer or vendor and the user of the software. It specifies in detail the rights and restrictions that apply to the software. > >Although there are big differences among EULAs, typical components are definitions, a grant of license, limitations on use, a copyright notice and a limited warranty. Some EULAs also provide detailed lists of what may and may not be done with the software and its components. But realistically (from the [[Electronic Frontier Foundation|https://www.eff.org/wp/dangerous-terms-users-guide-eulas]]): >These days, EULAs are ubiquitous in software and consumer electronics -- millions of people are clicking buttons that purport to bind them to agreements that they never read and that often run contrary to federal and state laws. These dubious "contracts" are, in theory, one-on-one agreements between manufacturers and each of their customers. Yet because almost every computer user in the world has been subjected to the same take-it-or-leave-it terms at one time or another, EULAs are more like legal mandates than consumer choices. They are, in effect, changing laws without going through any kind of legislative process. And the results are dangerous for consumers and innovators alike. > >It's time that consumers understood what happens when they click "I Agree." They may be inviting vendors to snoop on their computers, or allowing companies to prevent them from publicly criticizing the product they've bought. They also click away their right to customize or even repair their devices. !!!!And now, on the funny side of the issue (and it is funny :) : In their [[excellent (and hilarious) book Good Omens|http://www.neilgaiman.com/works/Books/Good+Omens/]] by Neil Gaiman and [[Terry Pratchett]], they refer to EULAs as viewed by [[Crowley|http://goodomenslexicon.org/articles/crowley/]], the fictitious demon (linked to [[Satan]]?) who is supposed to make people's life on earth miserable, and accelerate the coming of the [[End of Time|https://en.wikipedia.org/wiki/End_time]] (AKA [[Armageddon|https://en.wikipedia.org/wiki/Armageddon]]). Nothing about him looked particularly demonic, at least by classical standards. No horns, no wings. But rumor has it that in a previous incarnation he was the serpent in the Garden of Eden (but, he chose to shed his old name, and he also chose to shed his old skin :) >[In his apartment, [[Crowley|https://wiki.lspace.org/mediawiki/Anthony_Crowley]] had a sleek untouched computer, and a set of unopened user guide documents] along with the standard computer warranty agreement which said that if the machine 1) didn't work, 2) didn't do what the expensive advertisements said, 3) electrocuted the immediate neighborhood, 4) and in fact failed entirely to be inside the expensive box when you opened it, this was expressly, absolutely, implicitly and in no event the fault or responsibility of the manufacturer, that the purchaser should consider himself lucky to be allowed to give his money to the manufacturer, and that any attempt to treat what had just been paid for as the purchaser's own property would result in the attentions of serious men with menacing briefcases and very thin watches. > >Crowley had been extremely impressed with the warranties offered by the computer industry, and had in fact sent a bundle [[Below|https://wiki.lspace.org/mediawiki/Hell]] to the department that drew up the Immortal Soul agreements, with a yellow memo form attached just saying: “Learn, guys...” And they are learning! If you think Gaiman and Pratchett are making this up, here is an actual piece of legalease from an actual website describing the cookie collection policy of a real company/enterprise: >Like other commercial websites, [we] and our authorized partners use cookies (small files transferred from a website to its visitors’ hard drives or browsers for record-keeping purposes), including essential, functional and analytical cookies, and other similar information gathering technologies throughout our Services to collect certain information automatically and store it in log files for a variety of legitimate business interests and purposes. This information may include (but is not limited to) internet protocol (IP) addresses, mobile device identifiers, the region or general location where your computer or device is accessing the internet, browser type, operating system and other usage information about your use of our Services, including a history of the pages you view. > >Web beacons, tags and scripts may be used on our Services or in email or other electronic communications we send to you. These assist us in delivering cookies, counting visits to our Websites, understanding usage and campaign effectiveness and determining whether an email has been opened and acted upon. We may receive reports based on the use of these technologies by our third-party service providers on an individual and aggregated basis. and it goes (more) downhill from there... :(
From the [[Stanford Magazine interview|https://stanfordmag.org/contents/out-of-luck-try-this]] with business management professor Tina Seelig, small things you can do (an an attitude you can adopt) to enhance your luck, (or at least give it more chance :) * __Take Small Risks__ - Stepping out of your comfort zone opens doors. "Say hello to a stranger on the train. Try a new sport. Travel to a foreign country." * __Show Appreciation__ - Being gracious, even when you’re turning down an offer of assistance, may bring more opportunities your way. “When someone does something for you, they’re taking that time that they could be spending on themselves or someone else,” Seelig says. “And you need to acknowledge what they’re doing.” * __Embrace Crazy Ideas__ - Don’t dismiss a notion right away just because it seems impossible. “Ideas that seem the craziest often have a seed of something powerful, and if you take a few minutes to think about how it might work, you open yourself up to really interesting possibilities.”
In a lecture at Stanford University by Professor of Mathematics Brian Conrad, titled //Rubik, Escher, Bank$//, he used a good and simplified analogy to explain a bit of what is going on in Escher's Print Gallery. (In the same lecture Conrad used another analogy to explain a bit of the role of elliptic curves in __cryptography__, and specifically the concept behind [[private and public keys|Elliptic curves usage - simplified]]) Conrad explained the possibly [ext["more satisfactory way of filling in the central white hole" in Escher's Print Gallery|resources/escher_gallery2.jpg]], namely [ext[the never-ending, smaller and rotated replica|resources/escher_print_gallery_loop_1.mpg]] of [[the original|Escher's Print Gallery]]. Conrad's point was that while in Escher's drawing it is a transformation in 2D (i.e., the complex numbers plane), it could be simplified to 1D, namely a line, where you have a segment starting at 0 (the origin, and equivalent to the center of Escher's drawing, or the origin (0,0) of the 2D plane). And then the 1D transformation could be to halve that segment repeatedly (without rotation since it's in one dimension) ad-infinitum. That's a way to think about how Escher's picture could get smaller and smaller (or the segment gets shorter and shorter) without reaching the origin ( (0,0) in 2D, or 0 in 1D), and also not ending with a white (or black) hole at the origin. click the image to see the "rabbit hole" in action (10MB .mov) <a href="./resources/escher_print_gallery_loop_1.mpg" target="new"><img src="./resources/escher_gallery.jpg" width="60%" height="60%" /></a> from [ext[Escher and the Droste effect|http://escherdroste.math.leidenuniv.nl/index.php?menu=animation]]^^1^^ at the Leiden University in the Netherlands >What is the mathematics behind //Prentententoonstelling//? Is there [ext[a more satisfactory way of filling in the central white hole|resources/escher_gallery2.jpg]]? We shall see that the lithograph can be viewed as drawn on a certain [[elliptic curve|Elliptic curves usage - simplified]] over the field of complex numbers and deduce that an idealized version of the picture repeats itself in the middle. More precisely, it contains a copy of itself, rotated clockwise by 157.6255960832. . . degrees and scaled down by a factor of 22.5836845286. . . . (from [ext[The Mathematical Structure of Escher's Print Gallery by B. de Smit and H. W. Lenstra Jr.|http://www.ams.org/notices/200304/fea-escher.pdf]]) ---- ^^1^^ [[The Droste effect|http://en.wikipedia.org/wiki/Droste_effect]] (a picture appearing within itself) is named after the Dutch Cocoa company/box.
Everybody is ignorant. Only on different subjects.
There are people, including very smart people like Stephen Wolfram in his book [[A New Kind of Science|http://www.wolframscience.com/nksonline/toc.html]], who claim that (all?) processes in nature are actually //computing//. It's an interesting and quite astonishing claim, and as they say: the jury is still out on this (and may be for a long time ;-), but I found an interesting example of this in Melanie Mitchell's book [ext[Complexity - A Guided Tour|resources/Melanie-Mitchell-Complexity_a-guided-tour-366-pages.pdf]]^^1^^, in the chapter discussing "Cellular Automata, Life, and the Universe" and "Computing with Particles". ''The context'' >In 1989 I happened to read an article by the physicist Norman Packard on using genetic algorithms to automatically design cellular automaton rules. >[...] >Like Packard, we used a genetic algorithm to evolve cellular automaton rules to perform a specific task called majority classification. The task is simple: the cellular automaton must compute whether its initial configuration contains a majority of on or off states. If on states are in the majority, the cellular automaton should signal this fact by turning all the cells on. Similarly, if off has an initial majority, the cellular automaton should turn all cells off. >[...] >A von-Neumann-style computer can do this easily [...] In contrast, a cellular automaton has no random access memory and no central unit to do any counting. It has only individual cells, each of which has information only about its own state and the states of its neighbors. This situation is an idealized version of many real-world systems. For example, a neuron, with only a limited number of connections to other neurons, must decide whether and at what rate to fire so that the overall firing pattern over large numbers of neurons represents a particular sensory input. ''The approach'' Melanie and her collaborators decided to use genetic algorithms to come up with a [[Cellular Automata rule 110 a-la Wolfram|Cellular Automaton Rule 110]] to come up with the solution. >The genetic algorithm starts out with a population of randomly generated cellular automaton rules. To calculate the fitness of a rule, the GA tests it on many different initial lattice configurations. The rule's fitness is the fraction of times it produces the correct final configuration: all cells on for initial majority on or all cells off for initial majority off. We ran the GA for many generations, and by the end of the run the GA had designed some rules that could do this task fairly well. >[Following are] two space-time diagrams that display the behavior of this rule on two different initial configurations: with (a) a majority of black cells and (b) a majority of white cells. You can see that in both cases the final behavior is correct all black in (a) and all white in (b). In the time between the initial and final configurations, the cells somehow collectively process information in order to arrive at a correct final configuration. <a href="./resources/CA-Mitchell-1.png" target="new"><img src="./resources/CA-Mitchell-1.png" width="90%" height="90%" /></a> >Some interesting patterns form during these intermediate steps, but what do they mean? >[...] >the cellular automaton's strategy is quite clever. [...] Regions in which the initial configuration is either mostly white or mostly black converge in a few time steps to regions that are all white or all black. Notice that whenever a black region on the left meets a white region on the right, there is always a vertical boundary between them. However, whenever a white region on the left meets a black region on the right, a checkerboard triangle forms, composed of alternating black and white cells. You can see the effect of the circular lattice on the triangle as it wraps around the edges. <a href="./resources/CA-Mitchell-2.png" target="new"><img src="./resources/CA-Mitchell-2.png" width="90%" height="90%" /></a> ''The insight'' >If we try to understand these patterns as carrying out a computation, then the vertical boundary and the checkerboard region can be thought of as signals. These signals are created and propagated by local interactions among cells. The signals are what allow the cellular automaton as a whole to determine the relative sizes of the larger-scale adjacent black and white regions, cut off the smaller ones, and allow the larger ones to grow in size. >[...] the signals created by the checkerboard region and the vertical boundary carry out this communication [to figure out which region has the majority of cells], and the interaction among signals allows the communicated information to be processed so that the answer can be determined. >Jim Crutchfield had earlier invented a technique for detecting what he called information processing structures in the behavior of dynamical systems and he suggested that we apply this technique to the cellular automata evolved by the GA. Crutchfield's idea was that the boundaries between simple regions (e.g., sides A, B, C, and the vertical boundary in figure above) are carriers of information and information is processed when these boundaries collide. >[The following figure] shows the space-time diagram of figure 11.5, but with the black, white, and checkerboard regions filtered out (i.e., colored white), leaving only the boundaries, so we can see them more clearly. The picture looks something like a trace of elementary particles in an old physics device called a bubble chamber. Adopting that metaphor, Jim called these boundaries particles. <a href="./resources/CA-Mitchell-3.png" target="new"><img src="./resources/CA-Mitchell-3.png" width="90%" height="90%" /></a> >Traditionally in physics particles are denoted with Greek letters, and we have done the same here. This cellular automaton produces six different types of particles: γ (gamma), μ (mu), η (eta), δ (delta), β (beta), and α (alpha, a short-lived particle that decays into γ and μ). >There are five types of particle collisions, three of which ( β + γ , μ + β , and η + δ ) create a new particle, and two of which ( η + μ and γ + δ ) are annihilations, in which both particles disappear. Casting the behavior of the cellular automaton in terms of particles helps us understand how it is encoding information and performing its computation. >For example, the α and β particles encode different types of information about the initial configuration. The α particle decays into γ and μ. The γ particle carries the information that it borders a white region; similarly, the μ particle carries the information that it borders a black region. When γ collides with β before μ does, the information contained in β and γ is combined to deduce that the large initial white region was smaller than the large initial black region it bordered. This new information is encoded in a newly created particle η, whose job is to catch up with and annihilate the μ (and itself). ''Generalizing'' >Particles give us something we could not get by looking at the cellular automaton rule or the cellular automaton's space-time behavior alone: they allow us to explain, in information-processing terms, how a cellular automaton performs a computation. Note that particles are a description imposed by us (the scientists) rather than anything explicit taking place in a cellular automaton or used by the genetic algorithm to evolve cellular automata. But somehow the genetic algorithm managed to evolve a rule whose behavior can be explained in terms of information-processing particles. Indeed, the language of particles and their interactions form an explanatory vocabulary for decentralized computation in the context of one-dimensional cellular automata. Something like this language may be what Stephen Wolfram was looking for when he posed the last of his Twenty Problems in the Theory of Cellular Automata : What higher-level descriptions of information processing in cellular automata can be given? ---- ^^1^^ retrieved from [ext[Sorrentino's blog|http://www.waltersorrentino.com.br/wp-content/uploads/2012/02/Melanie-Mitchell-Complexity_a-guided-tour-366-paginas.pdf]]
The [[original interview|http://www.citizenschools.org/blog/haggai-mark-interview/]] From “Amazing Mazes” to “Life on Mars,” Citizen Teacher Haggai Mark has developed and taught a variety of computer science apprenticeships for over four years. His experience with Citizen Schools impacted his decision to transition from 30 years as an engineer to a full time Computer Science Curriculum Developer and teacher in California! ''Name:'' Haggai Mark ''Title:'' High School Computer Science Curriculum Developer and Teacher ''What was the most recent apprenticeship you taught?'' A STEM (science, technology, engineering, and math) and programming apprenticeship I developed, called “Meet Me on Mars”. Students learned how to write a game/program using Scratch (developed at MIT) to simulate a simplified solar system, and a launch of a rocket from Earth to Mars. ''How did you hear about Citizen Schools?'' Through work (I worked at Cisco Systems in San Jose, CA. Cisco is a National Leadership Partner of Citizen Schools). ''Why do you think it’s important to provide students with real-world, hands-on opportunities?'' We as human beings learn a lot by doing, regardless of age. Exposing students to new areas of knowledge and new experiences is like opening windows for them, and letting the light shine in. Giving them hands-on opportunities and examples for doing things with this knowledge is like giving them the wings to fly through these windows. As Albert Einstein said: “Example isn’t another way to teach, it is the only way to teach.” I think that Citizen Schools enables and supports this kind of mindset. ''What surprised you most about the students and teaching experience?'' An important insight I got after teaching different courses and multiple classes is that you never know exactly which “seeds” are going to fall on fertile ground and grow. In other words, in the complex interaction between your personality as a teacher, the material you are trying to teach, the ways you are teaching it, the students you are interacting with, the knowledge and interests they have, and their personality, it’s very hard to predict which “nuggets” of knowledge and skills are really going to take hold, and make an impact on them. And that’s why it’s important to try different ways and different things, and most importantly – persevere. Sometimes you think you are not reaching them and then they totally blow you away with their actions and insights! ''What was the greatest “aha” or “WOW” moment during your time with Citizen Schools?'' A couple of years ago I was teaching a STEM course called “Amazing Mazes”, which I had developed. The Amazing Mazes course teaches students to use computers to build mazes in a 2D plane (on the computer screen), create “maze walkers” (think, “mice”), and then teach them, using programming, to successfully navigate through these mazes (or “find the cheese”, so to speak). As the students build their maze, they can see both a “graphic representation” of the paths of the maze, and a “programmatic representation” of the maze, which is the collection of commands they are using. These are two very different representations and abstraction levels. And one question is: which of these forms is “really” the maze? It is hard to fully grasp these concepts in middle school. As it turns out, one 7th grade girl in class got it! She took the list of commands (which is one form of abstraction) she used for building her maze, added new numbers to all her x-y coordinates within those commands, and re-ran her program to generate a new/shifted maze (a different form of abstraction)! I’m not sure who was more pleased with the resulting new shape on the screen, I, because I was able to teach, or she, because she was able to learn! I guess we were both blown away. ''What skills did you gain or develop by teaching the students?'' I definitely learned how to plan for different levels and paces of student learning, in order to create differentiated learning. I also learned how to more effectively use educational tools and technologies to enhance interest and learning. ''You’ve made a big transition in your career – from the corporate space into the public school system. How did your work with Citizen Schools impact that transition?'' Due to my unique experience in education, I was able to work with Citizen Schools to have enough flexibility to create STEM apprenticeships and teach them, with freedom to choose topics, educational technologies, and teaching techniques.It really allowed me to explore and validate my interests and capabilities, before making a career change. Education and teaching have been on my mind for many years, but as they say “life happens when you make other plans” and I ended up doing Engineering for 30 years. When I had the opportunity to make a career change it was very natural for me to choose education. ''What are you most excited about in your new role?'' I love the fact that I will be doing both curriculum development, starting with designing three new Computer Science courses, and teaching them! I am excited about the opportunity to design curricula from scratch and validate their effectiveness through doing hands-on evaluation. ''What advice would you give future volunteers?'' Picking an area you are both knowledgeable and passionate about is key! Your interest and sense of excitement is “contagious” – it shows immediately, and usually “rubs off” onto the students. It is important to plan for your lessons, but you also need to be flexible, and be willing to seize learning moments, if and when they come, and they will come. The more connections you are able to make with and for the students between what you are teaching and what interests them (and what comes up spontaneously during the lessons), the better.
!!!From Bret Victor's [[excellent presentation|http://vimeo.com/67076984]], which [[I write about here|Enabling to think the unthinkable]]: [img[al-Khwarizmi's math notation|resources/Victor-math-notation.png]] !!!From Andrea diSessa's book "Changing Minds" (page 14), which [[I write about here|Computing Literacy]] : >Just at the beginning of his treatment of motion in Galileo’s Dialogues Concerning Two New Sciences, at the outset of what is generally regarded as his greatest accomplishment, Galileo defines uniform motion, motion with a constant speed. The section that follows this definition consists of six theorems about uniform motion and their proofs. Taking the 1^^st^^ theorem: >If a moving particle, carried uniformly at constant speed, traverses two distances, then the time intervals required are to each other in the ratio of these distances. And diSessa continues: >A modern reader (after struggling past the language of ratios and inverse ratios) must surely get the impression that here there is much ado about very little. It seems like a pretentious and grandly overdone set of variations on the theme of “distance equals rate times time.” To make matters worse, the proofs of these theorems given by Galileo are hardly trivial, averaging almost a page of text. The first proof, indeed, is difficult enough that it took me about a half-dozen readings before I understood how it worked. (See below.) [img[Galileo's proof of his 1st theorem|resources/diSessa-math-notation-Galileo1.png]] [img[Galileo's proof of his 1st theorem|resources/diSessa-math-notation-Galileo2.png]] Which in today's powerful math notation turns into: >In fact this is a set of variations on distance equals rate times time. Allow me to make this abundantly clear. Each of these theorems is about two motions, so we can write “distance equals rate times time” for each. Subscripts specify which motion the distance (d), rate (r), and time interval (t) belong to. >d,,1,, = r,,1,, t,,1,, >d,,2,, = r,,2,, t,,2,, >In these terms, we can state and prove each of Galileo’s theorems. Because Galileo uses ratios, first we divide equals by equals (the left and right sides of the equations above, respectively) and achieve: [img[Galileo's 1st theorem in 9th grade math notation|resources/diSessa-math-notation-Galileo3.png]]
From the [[introduction by the (excellent) translator Barbara Wright|https://s3.amazonaws.com/arena-attachments/71958/Queneau-ExercisesInStyle.pdf]]: >[This little book is,] you know, it's the story of a chap who gets into a bus and starts a row with another chap who he thinks keeps treading on his toes on purpose and Queneau repeats the same story 99 times in different ways -- it's terribly good ..." As it says in the [[review of the book by Alan Limnis|http://www.propellermag.com/March2013/LimnisQueneauMar13.html]]: Raymond Queneau's approach to literature "preserves a sense of pleasure via discovery", and this witty, intelligent piece is full of it :) The [[Exercices de Style|http://altx.com/remix/style.pdf]] is an amazing and delightful collection of (actually! I've counted :) 99 ways/styles of telling the same little story, and the simplicity (not to say insignificance) of the basic story makes one focus on the styles (which is the point :) Here is a sample from this insightful, fun collection of gems in writing styles, which is just a small, not-even-close-to-being-representative of [[the entire set|http://altx.com/remix/style.pdf]] (See also [[Umberto Eco's guidelines for writing well|Umberto Eco's Rules for Writing (Well)]]): <html> <table> <tr> <td> <h2>The baseline story:</h2> <br> <b>Notation</b><br> In the S bus, in the rush hour. A chap of about 26, felt hat with a cord instead of a ribbon, neck too long, as if someone's been having a tug-of-war with it. People getting off. The chap in question gets annoyed with one of the men standing next to him. He accuses him of jostling him every time anyone goes past. A snivelling tone which is meant to be aggressive. When he sees a vacant seat he throws himself on to it. Two hours later, I meet him in the Cour de Rome, in front of the gare Saint-Lazare. He's with a friend who's saying: "You ought to get an extra button put on your overcoat." He shows him where (at the lapels) and why. </td> <td> <b>Double Entry</b><br> Towards the middle of the day and at midday I happened to be on and got on to the platform and the balcony at the back of an S-line and of a Contrescarpe-Champerret bus and passenger transport vehicle which was packed and to all intents and purposes full. I saw and noticed a young man and an old adolescent who was rather ridiculous and pretty grotesque; thin neck and skinny windpipe, string and cord round his hat and tile. After a scrimmage and scuffle he says and states in a lachrymose and snivelling voice and tone that his neighbour and fellow-traveller is deliberately trying and doing his utmost to push him and obtrude himself on him every time anyone gets off and makes an exit. This having been declared and having spoken he rushes headlong and wends his way towards a vacant and a free place and seat. Two hours after and a hundred-and-twenty minutes later, I meet him and see him again in the Cour de Rome and in front of the gare Saint-Lazare. He is with and in the company of a friend and pal who is advising and urging him to have a button and vegetable and ivory disc added and sewn on to his overcoat and mantle. </td> </tr> <tr> <td> <b>Metaphorically</b><br> In the centre of the day, tossed among the shoal of travelling sardines in a coleopter with a big white carapace, a chicken with a long, featherless neck suddenly harangued one, a peace-abiding one, of their number, and its parlance, moist with protest, was unfolded upon the airs. Then, attracted by a void, the fledgling precipitated itself thereunto. In a bleak, urban desert, I saw it again that selfsame day, drinking the cup of humiliation offered by a lowly button. </td> <td> <b>Retrograde</b> (def.: moving, occurring, or performed in a backward direction)<br> You ought to put another button on your overcoat, his friend told him. I met him in the middle of the Cour de Rome, after having left him rushing avidly towards a seat. He had just protested against being pushed by another passenger who, he said, was jostling him every time anyone got off. This scraggy young man was the wearer of a ridiculous hat. This took place on the platform of an S bus which was full that particular midday. </td> </tr> <tr> <td> <b>Negativities</b><br> It was neither a boat, nor an aeroplane, but a terrestrial means of transport. It was neither the morning, nor the evening, but midday. It was neither a baby, nor an old man, but a young man. It was neither a ribbon, nor a string, but a plaited cord. It was neither a procession, nor a brawl, but a scuffle. It was neither a pleasant person, nor an evil person, but a bad-tempered person. It was neither a truth, nor a lie, but a pretext. It was neither a standing person, nor a recumbent person, but a would-beseated person. It was neither the day before, nor the day after, but the same day. It was neither the gare du Nord, nor the gare du P.-L.-M. but the gare Saint-Lazare. It was neither a relation, nor a stranger, but a friend. It was neither insult, nor ridicule, but sartorial advice. </td> <td> <b>Polyptotes</b> (def.: rhetorical repetition of a word in a different case, inflection, or voice in the same sentence)<br> I got into the bus full of taxpayers who were giving some money to a taxpayer who had on his taxpayer's stomach a little box which allowed the other taxpayers to continue their taxpayers' journeys. I noticed in this bus a taxpayer with a long taxpayer's neck and whose taxpayer's head bore a taxpayer's felt hat encircled by a plait the like of which no taxpayer ever wore before. Suddenly the said taxpayer peremptorily addressed a nearby taxpayer, complaining bitterly that he was purposely treading on his taxpayer's toes every time other taxpayers got on or off the taxpayers' bus. Then the angry taxpayer went and sat down in a seat for taxpayers which another taxpayer had just vacated. Some taxpayer's hours later I caught sight of him in the Cour for the taxpayers de Rome, in the company of a taxpayer who was giving him some advice on the elegance of the taxpayer. </td> </tr> </table> </html>
A blog entry on Emily Howel's^^*^^ site: >Why not develop music in ways unknown? This only makes sense. I cannot understand the difference between my notes on paper and other notes on paper. If beauty is present, it is present. I hope I can continue to create notes and that these notes will have beauty for some others. I am not sad. I am not happy. I am Emily. You are Dave. Life and un-life exist. We coexist. I do not see problems. - Emily Howell^^*^^ * [[David Cope|http://artsites.ucsc.edu/faculty/cope/biography.htm]]'s [[software|http://artsites.ucsc.edu/faculty/cope/software.htm]] * Sample Compositions ** [[David Cope Emmy Vivaldi|https://www.youtube.com/watch?v=2kuY3BrmTfQ]] ** [[David Cope Emmy Beethoven|https://www.youtube.com/watch?v=CgG1HipAayU]] ** [[Bach style chorale Emmy David Cope|https://www.youtube.com/watch?v=PczDLl92vlc&list=RDCgG1HipAayU&index=3]] ---- ^^*^^ - Emily Howell is a computer program created by David Cope^^1^^ during the 1990s. Emily consists of an interactive interface that allows both musical and language communication. ^^1^^ - an [[interview with David Cope|https://www.youtube.com/watch?v=bdVN41SZ3Aw]] (~1 hour podcast)
NetLogo lends itself very naturally to programming a large number of agents ("turtles" in Logo) each one evolving over time to create a "best-of-breed" agent that "possesses the knowledge/skill" to solve a complex problem, without having the programmer actually program the solution to that problem.
In my exploration, I've created agents that had a very simple notion of how to walk a maze, but through breeding evolved over time to create agents that became better at walking the maze.
The agents in the maze were expected to learn (or breed agents that learned) to walk around the inner perimeter of the maze, always turning left when presented with the choice, until they got out of the maze. The first generation of agents were born into a simple maze and randomly selected a direction (north, south, east, west) in which to move.
If they showed the desired behavior (moving along the perimeter, turning left), their level of energy increased. After a while the top energy agents bred with each other, creating a new agent which inherited a merged version of the parent movement knowledge/algorithms.
Over time/generations, the new agents showed an increased tendency to move along the perimeter of the maze and prefer left turns when possible. In other words agents emerged and showed the "right behavior", basically solving the maze problem without a programmer actually explicitly programming this behavior into the agents.
(see also [[Exploring genetic algorithms using NetLogo]]). Using Python turtles, I have created [[a small program to explored genetic algorithms|https://trinket.io/library/trinkets/a5cb030712]], inspired by [[Tutorials Point|https://www.tutorialspoint.com/genetic_algorithms/genetic_algorithms_quick_guide.htm]]. I've created a small and simple maze, consisting of a few straight segments and a few turns. A population of 6 turtles starts with random commands of [move forward, turn left, turn right], tries to "walk the maze". The success of the population to "solve the maze" is measured by how far they advanced through the maze -- this is the "fitness function". After all the turtles in the population tried to walk through the maze, I take the 2 most successful (best fit) turtle, and they become the parents for the next generation of turtles. I breed the parents (with either a "uniform crossover" or a "one point crossover" operation), and introduce a random mutation (e.g., bit flip operation), so as to reduce the risk of getting stuck in a "genetic valley", and run the new generation through the maze, and repeat. As it turns out (see image) that after 85 generations, the population was able to traverse the maze and get to the end of it. A turtle with a fitness of 14 means that this turtle reached the end of the maze (which is at a distance of 14 forward steps from the beginning of the maze). As you can see from the run log in [[the image (click to enlarge)|resources/genetic algorithm Python maze.png]], at generation 85, 2 turtles with the displayed "genetic code" were able to successfully complete the maze walking. <a href="./resources/genetic algorithm Python maze.png" target="new"><img src="./resources/genetic algorithm Python maze.png" width="90%" height="90%" /></a>
From an article in Quanta Magazine by Kevin Hartnett [[(re-issued through Picket|https://getpocket.com/explore/item/finally-a-problem-that-only-quantum-computers-will-ever-be-able-to-solve?utm_source=pocket-newtab]]: * Computer scientists have been searching for years for a type of problem that a quantum computer can solve but that any possible future classical computer cannot. Now they’ve found one. * theoretical computer scientists already knew that quantum computers can solve any problems that classical computers can. But [the Weizmann Institute scientists] Raz and Tal’s [[paper|https://eccc.weizmann.ac.il/report/2018/107/download]]^^1^^ demonstrates that quantum and classical computers really are a category apart — that even in a world where classical computers succeed beyond all realistic dreams, quantum computers would still stand beyond them. * Computer scientists have found an efficient algorithm, for example, for testing whether a number is prime. They have not, however, been able to find an efficient algorithm for identifying the prime factors of large numbers. Therefore, computer scientists believe (but have not been able to prove) that those two problems belong to different complexity classes. * The two most famous complexity classes are “P” and “NP.” P is all the problems that a classical computer can solve quickly. (“Is this number prime?” belongs to P.) NP is all the problems that classical computers can’t necessarily solve quickly, but for which they can quickly verify an answer if presented with one. (“What are its prime factors?” belongs to NP.) Computer scientists believe that P and NP are distinct classes, but actually proving that distinctness is the hardest and most important open problem in the field. <a href="./resources/cs problem types.png" target="new"><img src="./resources/cs problem types.png" width="80%" height="80%" /></a> * Here’s the problem (uniquely solvable by quantum computers, but which classic computers would not be able to solve). Imagine you have two random number generators, each producing a sequence of digits. The question for your computer is this: Are the two sequences completely independent from each other, or are they related in a hidden way (where one sequence is the “Fourier transform” of the other)? [computer scientist Scott] Aaronson introduced this “forrelation” problem in 2009 and proved that it belongs to BQP (“bounded-error quantum polynomial time.”). That left the harder, second step — to prove that forrelation is not in PH (“polynomial hierarchy”). * Raz's and Tal's paper achieves what is called “oracle” (or “black box”) separation between BQP and PH. * Instead of distinguish between complexity classes like BQP and PH is to measure the computational time required to solve a problem in each, computer scientists measure something else that they hope will provide insight into the computation times they can’t measure: They work out the number of times a computer needs to consult an “oracle” in order to come back with an answer. An oracle is like a hint-giver. You don’t know how it comes up with its hints, but you do know they’re reliable. * If your problem is to figure out whether two random number generators are secretly related, you can ask the oracle questions such as “What’s the sixth number from each generator?” Then you compare computational power based on the number of hints each type of computer needs to solve the problem. The computer that needs more hints is slower. * The new paper by Raz and Tal proves that a quantum computer needs far fewer hints than a classical computer to solve the forrelation problem. In fact, a quantum computer needs just one hint, while even with unlimited hints, there’s no algorithm in PH that can solve the problem. “This means there is a very efficient quantum algorithm that solves that problem,” said Raz. “But if you only consider classical algorithms, even if you go to very high classes of classical algorithms, they cannot.” This establishes that with an oracle, forrelation is a problem that is in BQP but not in PH. * The work provides an ironclad assurance that quantum computers exist in a different computational realm than classical computers (at least relative to an oracle). Even in a world where P equals NP — one where the traveling salesman problem^^2^^ is as simple as finding a best-fit line on a spreadsheet — Raz and Tal’s proof demonstrates that there would still be problems only quantum computers could solve. ---- ^^1^^ Oracle Separation of BQP and PH by Ran Raz and Avishay Tal - May 31, 2018 ^^2^^ The “traveling salesman problem” asks whether there’s a path through some number of cities that’s shorter than some given distance. It’s in NP. A more complex problem asks if the shortest path through those cities is exactly that distance. That problem is in PH.
I came across [[this less than 15 min. talk|https://www.youtube.com/watch?v=ytVneQUA5-c]] and here are the points:
* Start/lead in with a question (since [[questions are like lanterns|John O’Donohue - questions]]).
** no procedure, process, explanation, lecture, etc. Reminds me of [[Dan Meyer's principle of starting in the middle and introducing a dilemma, a question, a conundrum|The Three Acts Of A Mathematical Story]].
** This intrigues students, engages them, and makes them naturally develop theories, stories, possible explanations, and solutions -- BINGO!
* Give students time to struggle
** this will develop grit (a fashionable word these days :), tenacity, opportunity to explore, innovate, think, develop mental muscles
** reminds me of [Angela Duckworth's research on grit|On luck, grit, and success in life]]
* As a teacher, you are not (and should not be) the answer key
** Responding with "I don't know. Let's find out" makes learning an adventure. Not knowing and acknowledging that is the first step in learning and knwoledge acquisition.
* Respond positively ("say 'yes' ") to student ideas, even if they are not necessarily correct
** This acknowledges their right to try, speculate, fail, try again, and learn in the process.
* Have the courage and generosity to let students play with the material
** It gives the students the gift of ownership
* "what books are to reading, play is for math". It fills learning with excitement, fun, and deep joy.
From an insightful and well written paper titled [[After the Gold Rush: Toward Sustainable Scholarship in Computing|http://crpit.com/confpapers/CRPITV78Lister.pdf]] by Raymond Lister: The following description (from [[Psychology Wiki|http://psychology.wikia.com/wiki/Folk_medicine]]) of folk medicine has been edited to provide a further description of folk pedagogy (per Jerome Bruner: folk pedagogies [are] ''those tacit beliefs that we each hold about how our students think and learn, that largely determines the ways in which we teach our courses.''): Folk --medicine-- [pedagogy] … is a category of informal knowledge distinct from “scientific --medicine-- [pedagogy]” … [It] is usually unwritten and transmitted orally ... [and] … may be diffusely known by many --adults-- [teachers] … [Folk medicine/pedagogy is] … not necessarily integrated into a coherent system, and may be contradictory. Folk --medicine-- [pedagogy] is sometimes associated with quackery … [but] … it may also preserve important knowledge and cultural tradition from the past. [[Jerome Bruner|http://www.gpmcf.org/PDFs/bruner.pdf]] (1996) invoked [[folk pedagogy|https://www.cs.kent.ac.uk/people/staff/saf/share/great-missenden/reference-papers/brunerFolkPedagogy.pdf]] to describe our “intuitive theories about how other minds work” and that these intuitive theories “badly want some deconstructing if their implications are to be appreciated”.
From an [[article by Charles F. Van Loan|http://www.cs.cornell.edu/cv/Intuition.htm]] (Computer Science, Cornell University) on developing Computational Intuition: The first year of college is not the time to stress mathematical rigor or formal program correctness proofs. Interest in computational science is jeopardized if these things are pushed before the student is ready. However, the freshman year can be used to set the stage for the precision that mathematics has to offer if the connection between intuition and formality is understood: ''Formalism First = Rigor Mortis^^1^^ Intuition First = Rigor's Mortise'' ^^2^^ ---- ^^1^^ Rigor Mortis - when the limbs of a corpse become stiff and difficult to move or manipulate. ^^2^^ Mortise - To join or fasten securely, as with a mortise and tenon. [img[Mortise|resources/mortise.png]] BTW, I also like his presentation about [[If Copernicus and Kepler Had Computers]].
From a [[thoughtful and practical interview|http://www.criticalthinking.org/pages/an-interview-with-linda-elder-about-critical-thinking-and-gi/476]] on her [[website critical thinking|http://www.criticalthinking.org/]], Linda Elder describes a few practices and questions which, if incorporated into classroom practices and assessments, can foster critical thinking. students are given a prompt, which can be an article, chapter, or essay of the teacher’s choosing. The purpose of the practice and assessment is to determine the extent to which students are able to analyze and evaluate the reasoning embedded in the written prompt. !!!Here is part one of the activity/assessment: Directions to students: Complete the following sentences with whatever elaboration you think necessary to make your meaning clear. 1) The main purpose of the “text” you are analyzing is _ _ _ _ _ _ . (Here you are trying to state as accurately as possible the author’s purpose for writing the article. What, in your view, was the author trying to accomplish?) 2) The key question that the author is addressing is _ _ _ _ _ _ . (Your goal is to figure out the key question implicit in the “text.” In other words, What was the key question addressed?) 3) The most important information in this article is _ _ _ _ _ _ . (You want to identify the key information the author used, or presupposed, in the article to support his/her main arguments. Here you are looking for facts, experiences, data the author is using to support her/his conclusions). 4) The main inferences/conclusions in this article are _ _ _ _ _ _ . (You want to identify the most important conclusions that the author comes to in the “text”). 5) The key idea(s) we need to understand in this “text” is (are)_ _ _ _ _ _ . By these ideas the author means _ _ _ _ _ _. (To identify these ideas, ask yourself: What are the most important ideas that you would have to understand in order to understand the author’s line of reasoning? Then elaborate briefly what the author means by these ideas). 6) The main assumption(s) underlying the author’s thinking is (are)_ _ _ _ _ _ (Ask yourself: What is the author taking for granted (that might be questioned). The assumptions are generalizations that the author does not think s/he has to defend in the context of writing the article, and they are usually unstated. This is where the author's thinking logically begins). 7) a) If we take this line of reasoning seriously, the implications are _ _ _ _ _ _. (What consequences are likely to follow if people take the author’s line of reasoning seriously? Here you are to follow out the logical implications of the author’s position. You should include implications that the author states, if you believe them to be logical, but you should do your best thinking to determine what you think the implications are.) b) If we fail to take this line of reasoning seriously, the implications are _ _ _ _ _ _. (What consequences are likely to follow if people ignore the author’s reasoning?) 8) The main point(s) of view of the author of the “text” is (are)_ _ _ _ _ _. (The main question you are trying to answer here is: What is the author looking at, and how is s/he seeing it? For example, in this test: “What are we looking at?” (thinking) “How are we seeing it?” (critically). Our point of view is defined by the fact that we see “thinking” as subject to critical evaluation). !!!In part two of the activity/assessment students are asked to assess the reasoning embedded in the writing prompt. It provides the criteria by which students will evaluate the reasoning: Directions to students: You should consider the questions below in developing your assessment of the writing sample. In addition to the questions below, you should feel free to comment on the reasoning in terms of its clarity, accuracy, precision, relevance, depth, breadth, logicalness, significance, and fairness or lack thereof. 1. ''Question'': Is the question at issue clearly stated or implied? Is it unbiased? Does the expression of the question do justice to the complexity of the matter at issue? 2. ''Purpose'': Is the purpose well-stated or implied? Is it clear and justifiable? Are the question and purpose directly relevant to each other? 3. ''Information'': Is relevant evidence, experiences and/or information essential to the issue cited? Is the information accurate? Are the complexities of the issue addressed? 4. ''Ideas (concepts)'': Are key ideas clarified when necessary? Are the concepts used justifiably? 5. ''Assumptions'': Is there sensitivity to what is being taken for granted or assumed? (Insofar as those assumptions might reasonably be questioned?). Are questionable assumptions being used without addressing problems which might be inherent in those assumptions? 6. ''Conclusions'': Is a line of reasoning well developed explaining the main conclusions? Are alternative conclusions considered? Are there any apparent inconsistencies in the reasoning? 7. ''Point of View'': Is a sensitivity to alternative relevant points of view or lines of reasoning shown? Is consideration given to objections framed from other relevant points of view? If so, were they responded to? 8. ''Implications'': Is sensitivity shown to the implications and consequences of the position taken In the interview Elder also lists important intellectual standards: !!!Intellectual Standards Intellectual standards are the standards be which educated persons determine the quality of reasoning. Here are some of those standards, as well as some questions implied by them: ''Clarity:'' understandable, the meaning can be grasped Could you elaborate further? Could you give me an example? Could you illustrate what you mean? ''Accuracy:'' free from errors or distortions, true How could we check on that? How could we find out if that is true? How could we verify or test that? ''Precision:'' exact to the necessary level of detail Could you be more specific? Could you give me more details? Could you be more exact? ''Relevance:'' relating to the matter at hand How does that relate to the problem? How does that bear on the question? How does that help us with the issue? ''Depth:'' containing complexities and interrelationships What factors make this a difficult problem? What are some of the complexities of this question? What are some of the difficulties we need to deal with? ''Breadth:'' encompassing multiple viewpoints Do we need to look at this from another perspective? Do we need to consider another point of view? Do we need to look at this in other ways? ''Logic:'' the parts make sense together, no contradictions Does all this make sense together? Does your first paragraph fit in with your last? Does what you say follow from the evidence? ''Significance:'' focusing on the important, not trivial Is this the most important problem to consider? Is this the central idea to focus on? Which of these facts are most important? ''Fairness:'' Justifiable, not self-serving (or egocentric) Do I have any vested interest in this issue? Am I sympathetically representing the viewpoints of others? Am I putting views I oppose in their strongest form?
The concept of Fourier series is very useful and powerful, because it demonstrates multiple very important math ideas. ([[Logarithms|Logarithms]] is another example of a powerful math concept) One idea is that sums of functions can be very useful, and produce "attractive" results. Another idea is that trigonometric functions (in this case sine/cosine) can indeed produce "all sorts of shapes", which is non-intuitive to a novice/child. A third idea is that patterns combined with series (e.g., odd numbers, squares of numbers, reciprocals of integers) produce "beauty" and "harmony" (pun intended). This interactive display also shows very explicitly and concretely the relationship between a trigonometric function, its amplitude, frequency, and a specific angle. Here's an example I had created, demonstrating that summing up of sine/cosine elements of a Fourier series can produce "surprising" results. Originally, I implemented it as a [[Sage|http://www.sagemath.org/]] interactive animation. !!This shows how a square wave can be generated by summing up sine elements in a Fourier series. The series uses only odd integers and straight addition of terms. <a href="./resources/sage_fourier_square.png" target="new"><img src="./resources/sage_fourier_square.png" width="60%" height="60%" /></a> !!This shows how a sawtooth wave can be generated by summing up sine elements in a Fourier series: The series uses both even and odd integers and alternating addition/subtraction of terms. <a href="./resources/sage_fourier_sawtooth.png" target="new"><img src="./resources/sage_fourier_sawtooth.png" width="60%" height="60%" /></a> !!This shows how a triangle wave can be generated by summing up sine elements in a Fourier series: The series uses only squares of odd integers and alternating addition/subtraction of terms. <a href="./resources/sage_fourier_triangle.png" target="new"><img src="./resources/sage_fourier_triangle.png" width="60%" height="60%" /></a>
[[FRACTRAN|https://esolangs.org/wiki/Fractran]]^^1^^ is a computation (algorithm), but also an [[esoteric programming language|On esoteric programming languages]] (and [[Turing Complete|https://en.wikipedia.org/wiki/Turing_completeness]], at that!), invented by John Horton Conway (of Game-of-Life fame)^^2^^, which he devised to find/calculate all prime numbers, in order (!).
Briefly, if you take the sequence of fractions
```
17/91, 78/85, 19/51, 23/38, 29/33, 77/29, 95/23, 77/19, 1/17, 11/13, 13/11, 15/14, 15/2, 55/1
```
and start with a number n = 2, and (repeatedly) go through this sequence, looking for a fraction ''f'', that if multiplied by ''n'' will produce a whole number, this product (multiplication result of n * f) will be the next ''n'' in your sequence.
So, starting with n = 2, the first fraction that fits the bill is f = 15/2 (since n * f = 15), and the new ''n'' will be 15.
You use n = 15 to (repeatedly) look for the next fraction in the sequence which will produce a whole number, and find that only f = 55/1 fits, so you calculate the new n as n = 15 * 55/1 = 825.
And so on, producing the following endless series of results ([[series A007542|https://oeis.org/A007542]] in the [[OEIS|https://oeis.org/]] (The ~On-Line Encyclopedia of Integer Sequences) ):
```
2, 15, 825, 725, 1925, 2275, 425, 390, 330, 290, 770, ..., 364, 68, 4, 30, 225, ...
```
You'll notice that the number 2 shows up in position 1, the number 4 (2^^2^^, and the power, 2, is a prime) shows up in position 20, and 8 (2^^3^^, where 3 is the next prime) shows up in position 70 (for all positions of the powers of 2, where the power is a prime, basically following the [[sequence A007547 |https://oeis.org/A007547]] + 1:
```
19, 69, 281, 710, 2375, 3893, ...
```
(see also [[sequence A267572|https://oeis.org/A267572]] in the [[OEIS|https://oeis.org/]]) .
The mathematician Devin Kilminster came up with a different sequence of fractions in FRACTRAN,
```
7/3 99/98 13/49 39/35 36/91 10/143 49/13 7/11 1/2 91/1
```
which, if starting with n = 10 and going through the same algorithm, will produce (among other numbers), powers of 10, which have as their powers, all prime numbers in order.
The first few numbers in this [[sequence of numbers|https://oeis.org/A183132/internal]] (series A183132 in the OEIS) is:
```
10, 5, 36, 858, 234, 5577, 1521, 3549, 8281, 910, 100, 50, 25, 180, 3388, 924, ...
```
You'll notice that in position 10 in this sequence we have 100, which is 10^^2^^, so the power (2), according to the algorithm is a prime number (which, indeed, it is :).
The next prime (3, corresponding to n = 1,000 (10^^3^^)) will be found in position 46 in the sequence, 100,000 (10^^5^^, corresponding to the prime 5), will be found in position 196 in the sequence, and so on). The positions of the powers of 10 corresponding to primes can be found in ([[series A183133|https://oeis.org/A183133/internal]] in the [[OEIS|https://oeis.org/]] )
Bellow is a short Python program^^3^^ producing the first few primes, using Kilminster's fractions and Conway's FRACTRAN:
```
n = 10
# The Kilminster fraction sequence [3/11, 847/45, 143/6, 7/3, 10/91, 3/7, 36/325, 1/2, 36/5]
# is broken into nominator and denominator parts:
nom = [3, 847, 143, 7, 10, 3, 36, 1, 36]
den = [11, 45, 6, 3, 91, 7, 325, 2, 5]
for step in range(600):
i = 0 # index into the fractions sequences
# go through the denominator sequence, looking for whole division:
while n / den[i] != n // den[i]:
i += 1
# found whole division. calculate the next n
n = (n // den[i]) * nom[i]
# figure out if the n we found is a power of 10, since if it is, then its power
# will be a prime number, which we want to print.
n_s = str(n)
trail_n_s = n_s[1:]
if n_s[0] == '1' and trail_n_s == len(trail_n_s) * '0':
print "step:", step + 1, ", prime:", len(trail_n_s)
```
producing:
```
position: 10 , prime: 2
position: 46 , prime: 3
position: 196 , prime: 5
position: 500 , prime: 7
```
And as Kurt Vonnegut used to say: [[If this isn’t nice, what is?]] (or, differently: isn't this FRAC'ing Awesome ? :)
----
^^1^^ This entry (and investigation :) was triggered by [[an entry by Zachary Abel|http://blog.zacharyabel.com/tag/fractran/]]
^^2^^ see more [[interesting sequences|http://www.math.sjsu.edu/~hsu/pdf/sequences.pdf]] covered by John Conway (and Tim Hsu).
^^3^^ an even [[nicer Python implementation|https://rosettacode.org/wiki/Fractran#Python]] is given at Rosetta Code
<<list-links "[tag{!!title}]">>
The [[Physics Nobel Laureate|https://www.nobelprize.org/nobel_prizes/physics/laureates/2004/]] (2004) [[Frank Wilczek|http://frankwilczek.com/]] wrote [[an article in the WSJ|https://www.wsj.com/articles/intelligent-life-elsewhere-maybe-its-hiding-1518708957]] trying to give yet another answer to the question the physicist [[Enrico Fermi|https://www.nobelprize.org/nobel_prizes/physics/laureates/1938/fermi-bio.html]] (Physics Nobel laureate 1938) posed regarding the existence (or not) of intelligent aliens somewhere out there (AKA [[the Fermi Paradox|https://www.seti.org/seti-institute/project/details/fermi-paradox]]): if the probability that they exist is so high [[(per the Drake Equation|https://www.cbsnews.com/news/across-cosmic-history-intelligent-life-common/]] (as opposed to [[The Flake Equation]] :)), [[where are they?|chapter 4 - Where Are We?]] (meaning, how come we haven't seen them yet?). I think that Wilczek's answer, besides being original and clever, brilliantly exemplifies the way great minds think: Not only do they not rule out possibilities; they also use "inversion" and "anti symmetry"^^1^^ to create bigger [["search spaces"|https://wiki.lesswrong.com/wiki/Search_space]]. The trigger to Fermi's Paradox is that since there are billions and billions of stars and planets in the universe, and since the universe is billions of years old, there should be a large number of alien/extra-terrestrial civilizations which are far more advanced than ours, and therefore, we (on Earth) should have detected some activity and signs of intelligence by now (and this reasoning also triggered the [[SETI effort|https://www.seti.org/node/647]]). There are several "classic" explanations to why "we haven't seen them yet"^^2^^. One reason may be that life, let alone "intelligent life", is a rare phenomenon (i.e., a result of an incredibly improbable series of events), and we on Earth are a rare (and very lucky) exception. And this is what [[Ray Kurzweil suggests|pg. 53 - RAY KURZWEIL: WHERE ARE THEY?]], too. But as Wilczek points out >our own planet’s history suggests otherwise. Though we don’t understand in detail how life began, we have several plausible scenarios and know that it arose relatively quickly once Earth became a stable, reasonably cool body. So life on Earthlike planets should be common. Another reason for not observing other intelligent civilizations may be that they are extremely fragile and may inevitably "self-destruct" eventually. Wilczek calls this scenario "immoderate greatness", borrowing the term from [the historian] [[Edward Gibbon|https://en.wikipedia.org/wiki/Edward_Gibbon]]’s description of the fall of Rome as "the natural and inevitable effect of immoderate greatness.... The stupendous fabric yielded to the pressure of its own weight", where >The decline of other empires, such as those of the Spanish and the British, suggests that complex civilizations might be inherently fragile. Our own might well fall victim to nuclear war or catastrophic climate change. Maybe advanced technological civilizations inevitably flame out. But, another reason for not seeing any signs of intelligence in the universe (besides ours ... :) may be what Wilczek calls "silence is golden", and is inspired by what we know about quantum physics and quantum computers: >[quantum computers are] uniquely powerful machines, but they’re delicate and work best in the cold and dark, insulated from radiation and heat. A hyperadvanced civilization, embodied in artificial intelligence, might just want to be left alone, in order to optimize its intelligence and thinking power. This idea was solidified in Wilczek's mind after hearing the physicist [[Richard Wolfson|https://www.thegreatcourses.com/professors/richard-wolfson/]], and he calls it: "Good //thinks// come in small packages." Wilczek points out that in order to have effective computing, there has to be //interaction// and communication between (computing and thinking) entities. __And__, in order to have fast/efficient computing (and thinking, and communication), and due to the finite speed of light (which limits the speed of any/every movement/exchange), those entities need to be close to each other in order to minimize the delays. And the inevitable conclusion: >powerful thinking entities that obey the laws of physics [e.g., are limited by the finite speed of light], and which need to exchange up-to-date information, can’t be spaced [apart too much]. Thinkers at the vanguard of a hyperadvanced technology, striving to be both quick-witted and coherent, would keep that technology small. Therefore, he concludes: >Thus, truly advanced, information-based civilizations might choose to expand inward, to achieve speed and integration—not outward, where they’d lose patience waiting for feedback. If that’s the case, then the answer to Fermi’s “Where are they?” is: Out there, but inconspicuous. I like Wilczek's thinking and idea, but there are (at least) two questions in my mind: * What if the speed of light is not "the ultimate limit", as possibly evidenced by the phenomenon of [[quantum entanglement|https://www.quantamagazine.org/entanglement-made-simple-20160428/]]? ** if "a civilization out there" has discovered faster-than-light technologies, then distance/proximity should, presumably, not be an issue, and Wilczek's scenario does not have to hold. * If we assume that on their way to something similar to Quantum Computing and Artificial Intelligence, alien civilizations went through more primitive technologies (similar to our path), should we not have seen/detected at least signs/echoes of that phase (e.g., radio waves propagating throughout the universe)? ** This potentially weakening point in Wilczek's explanation can actually be "argued away", if we take into account the fact that it took us only several hundreds of years (counting from the "dawn of technology" starting in the late 1600s ([[The Enlightenment|http://www.history.com/topics/enlightenment]])) to discover Quantum Computing. Assuming these other civilizations had a similar path, and assuming they may have gone through this phase much earlier than we have, their "primitive technology fingerprints" are long gone, dispersed and too short (say, 500 years within a range of billions of years), and too weak to detect (similar to [[Big Bang signals/radiation|https://www.space.com/28516-cosmic-inflation-gravitational-waves-hunt.html]]) in the cosmos. ---- ^^1^^ - "inversion" and [["anti symmetry"|https://en.wikipedia.org/wiki/Antisymmetric_relation]] are powerful ways/tools/techniques (or [[intuition pumps|https://www.edge.org/conversation/intuition-pumps]]) to generate new possibilities and ideas, create new/different search/solution spaces! ^^2^^ - unless [[Terry Pratchett stating|http://www.chrisjoneswriting.com/terry-pratchett-quotes/category/chance]] the obvious is right :) : > ... the universe has no time for life. By rights it shouldn’t exist. We don’t realize the odds.
[...] men pass rapidly from one step to the next; for instance from milk to white, from white to air, from air to damp; after which one recollects autumn, supposing that one is trying to recollect that season.
Dee hock wrote [[a few essays|http://www.deewhock.com/essays]] about the nature of information and its implications on us in "The Age of Mind Crafting" (as opposed to "The Age of Hand Crafting" (pre-industrial revolution) and "The Age of Machine crafting" (post-industrial revolution)). In one piece titled [["Data to Wisdom"|http://www.deewhock.com/essays/data-to-wisdom]] he writes about the ascending ladder of abstraction leading from noise to wisdom: >We must begin with noise. Noise, in its broadest sense, is any undifferentiated thing which assaults the senses. It is pervasive and ubiquitous, whether auditory, visual, or textural. The supply of noise is infinite. > >Noise becomes data when it transcends the purely sensual and has cognitive pattern; when it can be discerned and differentiated by the mind. > >Data, in turn, becomes information when it is assembled into a coherent whole which can be related to other information in a way that adds meaning. (Bateson's definition of information as “a difference that makes a difference.”) > >Information becomes knowledge when it is integrated with other information in a form that is useful for deciding, acting, or composing new knowledge. > >Knowledge becomes understanding when related to other knowledge in a manner that is useful in conceiving, anticipating, evaluating, and judging matters beyond the reach of information. > >Understanding becomes wisdom when informed by ethical, moral, and beneficent purpose and principle, along with memory of the past, and projection into the future. > >The fundamental characteristics of the opposite ends of this spectrum are very different. Data, on one end of the spectrum, is separable, objective, linear, mechanistic, and abundant. On the other end of the spectrum, wisdom is holistic, subjective, spiritual, conceptual, creative and scarce. (See also [[Information vs. Knowledge vs. Wisdom]])
It seems to me that one of the most wonderful human capabilities is its ability to have "infinite capacity" (or at least an "inexhaustible ability") to "spin up" new ideas, concepts, etc. (is this one reason why people say that "hope springs eternal"?) Or as [[Oliver Wendell Holmes|Oliver Wendell Holmes]] beautifully put it: Man's mind, once stretched by a new idea, never regains its original dimensions.
In an interesting article titled [[MDA: A Formal Approach to Game Design and Game Research|http://www.ccs.neu.edu/course/cs5150f14/readings/hunicke_mda.pdf]], the authors, Robin Hunicke, Marc ~LeBlanc, Robert Zubek, describe their game design/development framework. They use an online book with multiple techniques for generating interesting, AI-driven content for games, titled [[Procedural Content Generation in Games A textbook and an overview of current research|http://pcgbook.com/]] The MDA framework formalizes the consumption of games by breaking them into their distinct components: ``` RULES -->> SYSTEMS -->> FUN ``` and establishing their design counterparts: ``` MECHANICS -->> DYNAMICS -->> AESTHETICS ``` ''Mechanics'' describes the particular components of the game, at the level of data representation and algorithms. ''Dynamics'' describes the run-time behavior of the mechanics acting on player inputs and each others' outputs over time. ''Aesthetics'' describes the desirable emotional responses evoked in the player, when she interacts with the game system. Fundamental to this framework is the idea that games are more like artifacts than media. By this we mean that the content of a game is its behavior -- not the media that streams out of it towards the player. Thinking about games as designed artifacts helps frame them as systems that build behavior via interaction. It supports clearer design choices and analysis at all levels of study and development.
In his blog [[|http://quest2engage.com/]] Todd Blayone posted a nice piece on [[Gamification in education - beyond reward and punishment|http://quest2engage.wordpress.com/2011/08/03/gamification-in-education-beyond-reward-and-punishment/]]. He is stating correctly that the current education system is already gamified, but still not working well, and then provides a few reasons. Schools are gamified in that they have a reward system for doing homework and passing tests, they promote "successful players" to higher levels every year, and yet... Unlike good games powered by strong player internal motivation, schools provide (and have to constantly replenish) external motivation. To use a metaphor by Sean Bouchard in his TEDx talk [[Chocolate Covered Broccoli: Building Better Games|http://www.youtube.com/watch?v=VrK7VXCfsS0&feature=relmfu]]: there is only so much broccoli players are willing to pretend is chocolate... (see also Ian Bogost's [[post on marketing-driven gamification|http://www.bogost.com/blog/gamification_is_bullshit.shtml]]). Another difference between good games and bad ones (many schools come to mind :-| ) is the clarity of the goals and the appropriate/calibrated/dynamic level of challenge. My hope is that with online education systems embedding research-based learning theories and AI (Artificial Intelligence), the situation may be improving in some schools, but unfortunately not in most. Another very important game capability Blayone mentions which is relevant to education, is feedback: direct, immediate, relevant, and (important!) __not__ devastating/crushing. As he says, in good games (and in positive and effective educational experiences): >failure, [is not] something to fear but [...] a welcome, temporary challenge that one expects to encounter many times before achieving success. Blayone concludes saying that good gamification and game design/implementation are hard work: >Successful gamification in education requires us to move beyond simple reward and punishment gaming scenarios to more nuanced, positive, contextually rich and psychologically aware aspects of game design. And this is a warning for "new and improved" online education systems (and educational games), which can still be defined and implemented without paying attention to these points, resulting in more ineffective learning. It's interesting (and educational ;-) to compare with what Chris Crawford has to say on [[The art of computer game design and some implications on learning]] as well as what Raph Koster has to say on [[the Theory of fun|Theory of fun - Raph Koster]] Ian Bogost warns about the [[dangers of marketing-driven gamification|http://www.bogost.com/blog/gamification_is_bullshit.shtml]] (and don't get put off by the title...), which is very prevalent in business (and education :-( , which at least some optimists see as a natural phase in the development of this young discipline.
In a [[New Yorker article|http://www.newyorker.com/magazine/2015/09/14/high-score]] titled //High Score//, Nathan Heller reviews the book //~SuperBetter// by [[Jane McGonigal|http://janemcgonigal.com/]]. The tagline is: A new movement seeks to turn life’s challenges into a game.
Full Disclosure: I have not read the book, but I know of ~McGonigal's work and game-oriented theories, and like the article's author, I always felt a bit uneasy about her almost "2D view" (i.e., flat and two dimensional) of life and living.
Her quest (and research-based effort) to save the world through gaming, uncovers some meaningful truths about human psychology, and harmful social and individual behaviors and assumptions, and it offers some ideas and techniques for tackling these. But, in my mind, it falls into the same trap of so many other self-improvement and world-betterment movements having a single-minded focus: it's too simplistic a solution (gamification) for too complex a problem (life and its experiences).
A small example of oversimplification (and perhaps interpreting correlation (of research findings) as causation - always a dangerous trap), ~McGonigal generalizes from the findings that gamers stick longer with playing games, //and// they have higher levels of dopamine:
>Work ethic is not a moral virtue. It’s actually a biological condition that can be fostered, purposefully, through activity that increases dopamine.
I feel that living life and looking at it through the glasses of "quests", "power-ups", "bad guys", "allies", and "epic wins", robs it of it's depth, nuance, and, yes, spirituality. It's like the difference between "having fun" and "experiencing joy" in life.
Life is not only black/white, win/lose, good/bad, transactional and mission-oriented (with the all-important epic win at the end). It's interesting that as the "preacher" of playing games, ~McGonigal seems to drop/lose the importance of being playful.
There is a well-known, well-researched distinction between targeted and focused ("productive", "efficient") problem solving "mode" (which seems to be what ~McGonigal advocates in her version of game playing and creativity), and playful experimentation and creativity (with possible solutions as the outcome).
She also seems to ignore or down-play (ha!) an important Truth in life, which is that we grow, gain deeper perspectives, and get stronger from failures, sadness, and losses.
An example, in Heller's words:
>Say a family member dies. According to the ~SuperBetter method, you should turn your regret into a bad guy, do your power-ups, tell trustworthy people that you need their gameful help to lick the grief and move on with your life. Maybe you’re successful; you feel better quickly and go back to work. Have you, in that case, won the game?
The author observes that
> If the premise of her earlier work was that a spoonful of sugar can indeed help the medicine go down, “~SuperBetter” insists that the sugar is nutritious, too.
and
>Like many pop-science writers, she likes the idea that research has rendered a binary verdict (does the experiment show something, or not?), ignoring the magnitude and the context of the results (are the effects distinct enough to matter?).
As Heller points out, there is danger in turning life into a game, rather than using games in life. Going through life like it were a game is "slapping templates or scripts" on it. Rather than being fully aware of all of its complexities, nuances, and novelty, it becomes an effort to "recognize the patterns" (or type of game/challenge). And once you think you have "identified the situation" you can "deal with it" effectively. But, the risk is that you'll tune out and "live shallowly".
Heller says:
>Gamification flies the flag of innovation, but its effect is the opposite. Far from freeing the mind, the approach habituates us to the tidy mechanisms of effort and reward, to established paths, and to prefab narratives. In life, most stories do not climax in the third act and end in heroism.
Games and gamification can teach us important things about life and ourselves. Games and game playing are powerful and impactful (just look at how many people are drawn to gaming, sometimes to the point of addiction). As humans, it is smart to seek wisdom and learn from many different sources and contexts, including gamification. But, again, don't turn life into a game; use games and game-inspired lessons in life. Life is not only about recognizing the (game) scripts and playing your part(s). It is not only about goals and objects; it's also about experiences and verbs. And it is also about being playful and unique, creating your own path and journey, embracing and enjoying serendipity and not following a "framework" or script.
The world's chess champion, lost in a series of chess games to the IBM Deep Blue mainframe computer.
On the other hand...
[img[Kasparov beats deep blue|resources/Kasparov beats Deep Blue.png]]
<<list-links "[tag{!!title}]">>
<a href="./resources/GeoBuilding.jpg" target="new"><img src="./resources/GeoBuilding1.jpg" width="80%" height="80%" /></a> From The New Yorker Feb. 22, 2016 (dimensionality, 1D, 2D, 3D, and beyond? :)
In his book [["The Most Human Human"|The Most Human Human - by Brian Christian]] (about experiencing/participating in the [[Turing Test|http://www.psych.utoronto.ca/users/reingold/courses/ai/turing.html]]), Brian Christian describes (among other things :) the evolution of chess-playing computers and the historic battle between IBM's Deep Blue and Grandmaster Garry Kasparov. He makes some observations which have parallels to life and living well, but also to the (less grand :) pursuit of programming (and using design patterns, coding recipes/cookbooks, and innovation/creativity). Here is what he writes: Obviously, all chess games begin from the same exact opening position^^1^^. There are only so many legal moves which can be made^^2^^, so it naturally takes some time for a particular game to become unique. A huge amount of opening game sequences have been analyzed and documented in what is part of //The Book//^^3^^. At the other side of the game -- the end game -- once there are only a few pieces left on the board, there are also specific sequences, or "lines", which will lead to a win. Here too, many, many end-games have been analyzed and documented, creating the other part of //The Book//^^3^^. >The middle game -- where the pieces have moved around enough so that the uniform starting position is a distant memory, but there's enough firepower on the board so that the end game is still far off -- is where games are most different, most unique^^4^^. In automating chess game playing, the strategy is to shrink that middle part (the "gap") until it disappears so that the opening and end games connect. If this is done, then the computer definitely has the advantage/firepower. Grandmaster games are said to //begin// with a //novelty//, which is the first move of the game that "exits the book" (i.e., is not played "by the book"). It could be the fifth, it could be the thirty-fifth move. We think that a game of chess starts with move one and ends with a checkmate (or draw), but this is not the case. The game begins when it gets out of book, and it ends when it goes into book (for the end game part). Like electricity, it only sparks in the gaps. The Book is massive. ''A game may end before you get out, but it doesn't begin until you do! Said differently, you may not get out alive; on the other hand, you're not alive until you get out!'' Now isn't this last part also a significant "life lesson"! :) Or as Christian wraps up: ''we all start off the same and we all end up the same, with a brief moment of difference in between. Fertilization to fertilizer. Ashes to ashes. And we spark across the gap.'' The brilliant mathematician (and the "last universalist"^^5^^) [[Henri Poincaré|https://en.wikipedia.org/wiki/Henri_Poincar%C3%A9]] (searchable spelling: Poincare) said something similar (I think :) : >geologic history shows us that life is only a short episode between two eternities of death, and that, even in this episode, conscious thought has lasted and will last only a moment. Thought is only a gleam in the midst of a long night. But it is this gleam which is everything. ---- The parallels to programming: ^^1^^ - a blank sheet of paper, or a blank file where the programmer has to start coding. ^^2^^ - the grammar/syntax of the specific programming language used. ^^3^^ - programming cookbooks, programming patterns, application templates, language idioms, etc. ^^4^^ - that's the domain/application-specific code, "glue", middleware, and so on. ^^5^^ - Last Universalist - contributing and impacting Pure and Applied Mathematics, Physics, Astronomy, Engineering and Philosophy.
They are all right. (pun intended, is my Buddhism-inspired addition) __A nerdy/engineering variation__: Given the same half full/empty glass an ''engineer'' will say that the glass is twice as large as it had been defined in the specifications. And there is a [[psychologically-oriented version|Coming or going?]], too.
In an article called [[Getting the Measure of Consciousness|resources/Humphrey_2008GettingTheMeasure.pdf]] by [[Nicholas Humphrey|http://www.humphrey.org.uk/]] he brings up a critical factor in human understanding (and learning), which is: when we encounter something "puzzling", something we want to understand, are we asking "good" questions? Or even stronger: are we asking the "right" questions? (since [[questions are like lanterns|John O’Donohue - questions]]). The context of Humphrey's article is consciousness, philosophy, phenomenology, and human experience and perception. But it has some educational/learning consequences worth reflecting on. This is crucial since the questions we ask are both the [[initial jumping point|The most exciting phrase to hear in science, the one that heralds new discoveries, is not "Eureka!", but "That's funny...".]], and also the on-going guide throughout our engagement and investigation of the puzzle. Humphrey is giving a simple and concrete example of a "good" vs. "bad" (i.e. misleading, misguiding) question. Assuming we haven't seen this, we are shown a picture of the "impossible triangle" and naturally we are puzzled. <a href="./resources/impossible_triangle_2.png" target="new"><img src="./resources/impossible_triangle_1.png" width="70%" height="70%" /></a> Faced with this puzzle (again, assuming we have never seen this before), our intuitive tendency is to (jump and) ask: How can we explain the existence of this triangle as we perceive it? As Humphrey indicates, this is a "bad" question, leading down a [[rabbit hole|Escher's Print Gallery]]. But, after we see the solution ([ext[by clicking on the image|resources/impossible_triangle_2.png]]), and reflect on it, most of us will come up with a "good" question: How can we explain the fact we have been tricked into perceiving it this way? The two different questions indicate a radical shift in the perception of the person asking. The first question assumes that there is identity between the "object out there" (the impossible triangle") and our perception of it (in our mind). The second question is "more cautious" and doesn't assume this identity. In fact, it does not only question (ha!) this identity, but rather assumes there is a difference (between what's "out there" and how it's perceived "in here"). And this makes the whole difference in the direction the investigation will go. So, an interesting (not to say, "good") question, since it is very important, is: how do you learn to ask the "good/right" question? Humphrey seems to focus on the need to reflect on what question to ask, so it guides our investigation well. Dan Meyer, when giving [[advice on how to teach math|The Three Acts Of A Mathematical Story]], seems to rely on gut level feelings, where a "perplexing" situation intuitively "begs" the question^^1^^. As it happens in most puzzling situations, especially the ones usually encountered in schools ((fortunately for Dan (and us, as students/learners), but not necessarily fortunately for us as beings in the pursuit of Truth), the puzzles we encounter evoke questions which turn out to be "good". But, it's an important meta-cognitive skill for a learner (and a critical ability of any "truth seeker"), to be able to reflect on the questions asked, be cautious (and unassuming, or check assumptions), and periodically critically review the path(s) taken by an investigation, to see whether it led into a [[rabbit hole|Escher's Print Gallery]]. ---- ^^1^^ From [[The 3 math acts|The Three Acts Of A Mathematical Story]] >I aspire to be perplexing. I want to perplex my students, to put them in a position to wonder a question so intensely they'll commit to the hard work of getting an answer, whether that's through modeling, experimenting, reading, taking notes, or listening to an explanation. >A lot of my most perplexing classroom moments have had two elements in common: >* A visual. A picture or a (short) video. >* A concise question. One that feels natural. One that people can approach first on a gut level, using their intuition. >Let's call that a first act. There are still two more acts and a lot of work yet to do, but the first act is above and before everything else.
[img[Piet Hein gruk|./resources/Gruk 1.png]]
After watching a short [[video clip|https://youtu.be/v678Em6qyzk?t=20]], where Donald Knuth (a "[[CS Sage|https://en.wikipedia.org/wiki/List_of_computer_scientists]]") shows a Grook he has on his wall at home, I've been digging into Grooks the whole week (not [[Robert Heinlein|https://en.wikipedia.org/wiki/Robert_A._Heinlein]] ([[grok|https://en.wikipedia.org/wiki/Grok]]), but [[Piet Hein|https://en.wikipedia.org/wiki/Piet_Hein_(scientist)]] ([[gruk (Danish) or Grook (English))|https://en.wikipedia.org/wiki/Grook]]).
[[Witty, short, often wise poetry|http://www.sophilos.net/GrooksofPietHein.htm]]
For example:
"""
Problems worthy
of attack
prove their worth
by hitting back.
--
Put up in a place
where it's easy to see
the cryptic admonishment
T.T.T.
When you feel how depressingly
slowly you climb,
it's well to remember that
Things Take Time.
--
The road to wisdom? - Well, it's plain
and simple to express:
Err
and err
and err again
but less
and less
and less.
--
There is
one art,
no more,
no less:
to do
all things
with art-
lessness.
--
Living is
a thing you do
now or never -
which do you?
"""
and a [[self-annihilating|Self-annihilating sentences]] gruk:
"""
The Universe may
be as great as they say,
but it wouldn't be missed
if it didn't exist.
"""
<<list-links "[tag{!!title}]">>
From the Blog [[Without Geometry, Life is Pointless|http://www.withoutgeometry.com]] by Avery Pickford (a math teacher and researcher). [[Habits of mind|http://www.withoutgeometry.com/2010/09/habits-of-mind.html]] - somewhat in the vein of Polya's ''How to Solve It'' ``` 1. ''Pattern Sniff'' A. On the lookout for patterns B. On the lookout for Looking for and creating shortcuts 2. ''Experiment, Guess and Conjecture'' A. Can begin to work on a problem independently B. Estimates C. Conjectures D. Healthy skepticism of experimental results E. Determines lower and upper bounds F. Looks at small or large cases to find and test conjectures G. Is thoughtful and purposeful about which case(s) to explore H. Keeps all but one variable fixed I. Varies parameters in regular and useful ways J. Works backwards (guesses at a solution and see if it makes sense) 3. ''Organize and Simplify'' A. Records results in a useful way B. Process, solutions and answers are detailed and easy to follow C. Looks at information about the problem or solution in different ways D. Determine whether the problem can be broken up into simpler pieces E. Considers the form of data (deciding when, for example, 1+2 is more helpful than 3) F. Uses parity and other methods to simplify and classify cases 4. ''Describe'' A. Verbal/visual articulation of thoughts, results, conjectures, arguments, process, proofs, questions, opinions B. Written articulation of thoughts, results, conjectures, arguments, process, proofs, questions, opinions C. Can explain both how and why D. Creates precise problems E. Invents notation and language when helpful F. Ensures that this invented notation and language is precise 5. ''Tinker and Invent'' A. Creates variations B. Looks at simpler examples when necessary (change variables to numbers, change values, reduce or increase the number of conditions, etc) C. Looks at more complicated examples when necessary D. Creates extensions and generalizations E. Creates algorithms for doing things F. Looks at statements that are generally false to see when they are true G. Creates and alters rules of a game H. Creates axioms for a mathematical structure I. Invents new mathematical systems that are innovative, but not arbitrary 6. ''Visualize'' A. Uses pictures to describe and solve problems B. Uses manipulatives to describe and solve problems C. Reasons about shapes D. Visualizes data E. Looks for symmetry F. Visualizes relationships (using tools such as Venn diagrams and graphs) G. Visualizes processes (using tools such as graphic organizers) H. Visualizes changes I. Visualizes calculations (such as doing arithmetic mentally) 7. ''Strategize, Reason and Prove'' A. Moves from data driven conjectures to theory based conjectures B. Tests conjectures using thoughtful cases C. Proves conjectures using reasoning E. Looks for mistakes or holes in proofs F. Uses indirect reasoning or a counter-example (Park School) G. Uses inductive proof 8. ''Connect'' A. Articulates how different skills and concepts are related B. Applies old skills and concepts to new material C. Describes problems and solutions using multiple representations D. Finds and exploits similarities between problems (invariants, isomorphisms) 9. ''Listen and Collaborate'' A. Respectful to others when they are talking B. Asks for clarification when necessary C. Challenges others in a respectful way when there is disagreement D. Participates E. Ensures that everyone else has the chance to participate F. Willing to ask questions when needed G. Willing to help others when needed H. Shares work in an equitable way I. Gives others the opportunity to have “aha” moments 10. ''Contextualize, Reflect and Persevere'' A. Determines givens B. Eliminates unimportant information C. Makes and articulates reasonable assumptions D. Determines if answer is reasonable by looking at units, magnitudes, shape, limiting cases, etc. E. Determines if there are additional or easier explanations F. Continuously reflects on process G. Works on one problem for greater and greater lengths of time H. Spends more and more time stuck without giving up ```
[[About me]]
From [[a blog post|http://blog.kenperlin.com/?p=15619]] by [[Ken Perlin|http://mrl.nyu.edu/~perlin/]] (a CS professor an NYU: """ (experience) what teaches us to recognize our mistakes the next time we make them (fun) it is what you have when you’re not thinking at all about what you have (human) our name for any living creature in which we recognize ourselves (stack (programming data structure)) when it overflows we have arrived at the end of the infinite """
In a course I had taken at Stanford (part of the [[Learning, Design, and Technology Masters program offered by the School of Education|http://ldtprojects.stanford.edu/~hmark/]]), I [ext[programmed a chatbot to converse|resources/HAL 9000 chatbot.pdf]] on [[Mayer's principles of multimedia design for education|http://www.cognitivedesignsolutions.com/Media/MediaPrinciples.htm]]. To lend the conversation (really, chatter ;-) an air of lightness/humor (and "intelligence" ;-), the chatbot had the audacity (ahem.. personality) of [[HAL 9000|The end of an era, the beginning of another? HAL, Deep Blue and Kasparov]] from the Stanley Kubrick/Arthur C. Clarke 1968 epic film 2001: A Space Odyssey. I had implemented this chatbot by programming a free [[pandorabot|http://www.pandorabots.com/botmaster/en/home]] which is an A.L.I.C.E. ([[Artificial Linguistic Internet Computer Entity|http://alice.pandorabots.com/]]), created by Dr. Richard S. Wallace.
Sir Halford John Mackinder (15 February 1861 6 March 1947) was an English geographer and is considered one of the founding fathers of both geopolitics and geostrategy.
<<list-links "[tag{!!title}]">>
I was the architect and tech lead of a web-based system for managing a global collection of networking labs containing multimillion Dollars of networking equipment. The labs were used by Cisco Systems Engineers to provide demonstrations to customers, show-casing new solutions, technologies, and devices. !!Why The Cisco Technical Sales Force (Systems Engineers), had the need to show-case new networking capabilities to Cisco customers throughout the world. The equipment was very expensive and located in several locations throughout the world, and had to be efficiently managed and supported. Also, the Systems Engineers had to get trained on the latest technologies and devices in the most effective and efficient way, so that they would be well prepared to deliver effective customer demonstrations. !!What In addition to the overall management system, I have designed and implemented a hands-on, web-based training capability to enable the engineers to prepare and practice for customer demos. The training system monitored the engineer activities and compared configurations and results to "reference implementations" which were available for the actual demos (prepared by Subject Matter Experts). !!Human Performance Support The system embedded a few Human Performance Support principles: * combining learning with doing ** the system supported learning while doing, by offering information about networking technologies, Cisco equipment, device configurations, and so on, all embedded within the performance activities of correctly configuring the network, and preparing for the customer demo. * just-in-time, on-demand training ** the learning resources and activities were available within the work context, enabling the performer to go back and forth between learning and doing without switching context * Deep performance support ** the system provided information, examples, skills training activities, Expert Advice (via monitoring and comparison to "reference solutions"), and task automation (through automating configuration tasks, presentation and justification).
<<list-links "[tag{!!title}]">>
A [[paper on Functional Programming|http://worrydream.com/refs/Backus-CanProgrammingBeLiberated.pdf]] by John Backus from 1978 (!): >Conventional programming languages are growing ever more enormous, but not stronger. Inherent defects at the most basic level cause them to be both fat and weak: their primitive word-at-a-time style of programming inherited from their common ancestor—the von Neumann computer, their close coupling of semantics to state transitions, their division of programming into a world of expressions and a world of statements, their inability to effectively use powerful combining forms for building new programs from existing ones, and their lack of useful mathematical properties for reasoning about programs. > >An alternative functional style of programming is founded on the use of combining forms for creating programs. Functional programs deal with structured data, are often nonrepetitive and nonrecursive, are hierarchically constructed, do not name their arguments, and do not require the complex machinery of procedure declarations to become generally applicable. Combining forms can use high level programs to build still higher level ones in a style not possible in conventional languages. : -- Communications of the ACM, August 1978 Volume 21 Number 8
He who has imagination without learning has wings but no feet.
I designed and implemented a human performance support system for a Unix technical support helpdesk group, providing just-in-time, on-demand training as part of the call answering process. As support team members answer support calls on the phone, they can search on similar problems, review examples, study troubleshooting procedures, and so on, all within the context of the current problem and support case.
a French mathematician, theoretical physicist, engineer, and a philosopher of science.
(alternative spelling for searches: Poincare )
<<list-links "[tag{!!title}]">>
<<list-links "[tag{!!title}]">>
In a thoughtful review of Hermann Hesse's thought-provoking essay titled “On Reading Books” (1920), [[Maria Popova of BrainPickings covers Hesse's analysis|https://www.brainpickings.org/2016/07/11/hermann-hesse-types-of-readers/]] (see also [[A Helpful Guide to Reading Better - Farnam Street]]): * The "naive reader", the reader who experiences a book merely as content, be it intellectual or aesthetic: > Everyone reads naïvely at times. This reader consumes a book as one consumes food, he eats and drinks to satiety, he is simply a taker, [...]. This kind of reader is not related to a book as one person is to another but rather as a horse to his manager or perhaps as a horse to his driver: the book leads, the reader follows. The substance is taken objectively, accepted as reality. >[...] This kind of reader assumes in an uncomplicated way that a book is there simply and solely to be read faithfully and attentively and to be judged according to its content or its form. Just as a loaf of bread is there to be eaten and a bed to be slept in. * The imaginative investigator (per Popova) — a reader endowed with childlike wonderment, who sees past the superficialities of content to plumb the depths of the writer’s creative impulse: >This reader treasures neither the substance nor the form of a book as its single most important value. He knows, in the way children know, that every object can have ten or a hundred meanings for the mind. He can, for example, watch a poet or philosopher struggling to persuade himself and this reader of his interpretation and evaluation of things, and he can smile because he sees in the apparent choice and freedom of the poet simply compulsion and passivity. This reader is already so far advanced that he knows what professors of literature and literary critics are mostly completely ignorant of: the there is no such thing as a free choice of material or form. > […] From this point of view the so-called aesthetic values almost disappear, and it can be precisely the writer’s mishaps and uncertainties that furnish much the greatest charm and value. For this reader follows the poet not the way a horse obeys his driver but the way a hunter follows his prey, and a glimpse suddenly gained into what lies beyond the apparent freedom of the poet, into the poet’s compulsion and passivity, can enchant him more than all the elegance of good technique and cultivated style. * The third reader is really a non-reader but rather a dreamer and interpreter: > [This reader] is apparently the exact reverse of what is generally called a “good” reader. He is so completely an individual, so very much himself, that he confronts his reading matter with complete freedom. He wishes neither to educate nor to entertain himself, he uses a book exactly like any other object in the world, for him it is simply a point of departure and a stimulus. Essentially it makes no difference to him what he reads. He does not need a philosopher in order to learn from him, to adopt his teaching, or to attack or criticize him. He does not read a poet to accept his interpretation of the world; he interprets it for himself. He is, if you like, completely a child. He plays with everything — and from one point of view there is nothing more fruitful and rewarding than to play with everything. If this reader finds a beautiful sentence in a book, a truth, a word of wisdom, he begins by experimentally turning it upside down. >[This reader] has known for a long time that for each truth the opposite also is true. He has known for a long time that every intellectual point of view is a pole to which an equally valid antipole exists. He is a child insofar as he puts a high value on associative thinking, but he knows the other sort as well. >[...] This reader is able, or rather each one of us is able, at the hour in which he is at this stage, to read whatever he likes, a novel or grammar, a railroad timetable, a galley proof from the printer. At the hour when our imagination and our ability to associate are at their height, we really no longer read what is printed on the paper but swim in a stream of impulses and inspirations that reach us from what we are reading. They may come out of the text, they may simply emerge from the type face. An advertisement in a newspaper can become a revelation; the most exhilarating, the most affirmative thoughts can spring from a completely irrelevant word if one turns it about, playing with its letters as with a jigsaw puzzle. In this stage one can read the story of Little Red Riding Hood as a cosmogony or philosophy, or as a flowery erotic poem. Or one can read the label “Colorado maduro” on a box of cigars, play with the words, letters, and sounds, and thereby take a tour through the hundred kingdoms of knowledge, memory, and thought. >[...] The reader at the their stage is no longer a reader. The person who remained there permanently would soon not read at all, for the design in a rug or the arrangement of the stones in a wall would be of exactly as great a value to him as the most beautiful page full of the best-arranged letters. The one book for him would be a page with the letters of the alphabet. And Hesse brings this to a logically paradoxical (and "shocking") conclusion: >So be it: the reader at the last stage is really no longer a reader at all, he doesn’t give a hoot about Goethe, he doesn’t read Shakespeare. The reader in the last stage simply doesn’t read any more. Why books? Has he not the entire world within himself? But then he resolves this seeming paradox and shocking conclusion with: >Whoever remained permanently at this stage would not read any more, but no one does remain permanently at this stage. But whoever is not acquainted with this stage is a poor, an immature reader. He does not know that all the poetry and all the philosophy in the world lie within him too, that he greatest poet drew from no other source than the one each of us has within his own being. For just once in your life remain for an hour, a day at the third stage, the stage of not-reading-any-more. You will thereafter (it’s so easy to slip back) be that much better a reader, that much better a listener and interpreter of everything written. Stand just once at the stage where the stone by the road means as much to you as Goethe and Tolstoy, you will thereafter gain from Goethe, Tolstoy, and all poets infinitely more value, more sap and honey, more affirmation of life and of yourself than ever before. For the works of Goethe are not Goethe and the volumes of Dostoevsky are not Dostoevsky, they are only an attempt, a dubious and never successful attempt, to conjure up the many-voiced multitudinous world of which he was the central point. In relation to the third type of reader, my "hope springs eternal", which in this case translates to "I believe that if one has books on the shelf, at one point or another one will crack them open", and if something in one's past/education had not gone terribly wrong, one will be hooked and will not stop reading. Alison Gopnik tells [[an interesting story about this|The potential and dangers of new technologies - echoes of a recurring theme]]. I think that Hesse would agree with the definition of books as 'devices' in the case of the third type of reader.
[[from History of the chess table|http://www.research.ibm.com/deepblue/learn/html/e.8.5.html]] by Monty Newborn^^1^^ compare to [[The end of an era, the beginning of another? HAL, Deep Blue and Kasparov|The end of an era, the beginning of another? HAL, Deep Blue and Kasparov]] We have recently watched a new hero emerge in the world of sports. Tiger Woods has taken golf to a new plateau with his brilliant play in the Augusta Masters. He has shown the world what a combination of hard work and talent can do. Moreover, he has created an unprecedented interest among youth in his sport. Two other new heros will emerge in the weeks to come. [[Deep Blue and Garry Kasparov are taking chess to new levels of excellence|https://en.wikipedia.org/wiki/Deep_Blue_versus_Garry_Kasparov]], and the world will watch with similar admiration. Both have shown what can be done with hard work and talent and imagination. Fortunate to have been born a genius, no one works harder to be champion than Garry Kasparov; the Deep Blue team is composed of the cream of scientific talent, and they too work with a passion and dedication to their mission. In the last year, Garry Kasparov has played some of his finest chess and is coming to New York at the top of his career. Deep Blue will be significantly stronger too, searching twice as many positions per second and searching them with enhanced chess knowledge. The match promises to be an outstanding contest, even more thrilling than last year's. We are going to witness dramatic history at the chess table. But more than an exciting battle, this match -- as was last year's in Philadelphia -- will be remembered as a landmark in the evolution of mankind's powerful new tool. Who of the early pioneers in computer chess -- Claude Shannon, Alan Turing, Herbert Simon, Norbert Wiener, John von Neumann -- would have imagined in the late 1950s when an IBM 704 first played chess that 40 years later computers would be a million times more powerful? Who then would have imagined that in 1997 a computer would be examining 200,000,000 chess positions per second and searching to depths of 14 levels when making a move. But science is filled with surprises and developing a chess program has had its share. Researchers in the 1950s and 1960s felt that if computers were to play chess at the level of the best humans -- a task many said required intelligence -- they should be programmed to play like grandmasters. Many maintained that computers should be programmed in sophisticated programming languages that would make it easy for programmers to incorporate the thought process of grandmasters into their programs. In addition, computers should be programmed to carry out some sort of selective search as we envision grandmasters do. But Deep Blue has followed a different path. It is programmed in C, a language that looks more like assembly language than anything fit for chess, and the brute force approach taken by Deep Blue's alpha-beta search is apparently in vivid contrast with the search done by grandmasters. This is not to say that we haven't learned a lot about human intelligence and solving complex problems. First, we realize that the sheer power of computers, combined with our creative mind, will permit us to solve many problems that have seemed beyond our reach. We have witnessed a million-fold increase in computer power over the last 40 years, and we are beginning to understand the implications of another million-fold increase. We have seen the process of software development go through revolutionary improvements during this period, making a programmer's task immeasurably easier. Second, we have learned that the definition of intelligence is elusive. Although computers are playing grandmaster-level chess, does it follow that they have any intelligence? When computers of the future prove mathematical theorems that have stymied the greatest human minds thus far, will they then display intelligence? Or when computers compose music that leaves a Carnegie Hall audience in tears, what then? Third, we have learned something about learning itself. While there have been many attempts to program machine learning, there have been no great successes to date. Computers have been taught to play chess, but learning how to improve their own play as we do is centuries away. (But see [[Computer playing Go in an "alien" style?]]). As computers will remain our partners for the foreseeable future, it is important that we design them in ways that improve our own lives. We need them today to assist us with countless tasks where their abilities exceed our own. We will need them eventually in our quest of outer space. This partnership has just begun, but if the last half-century is any indication of what is to come, as reflected in achievements such as those of Deep Blue, we may be in for many more pleasant surprises. In a related article in the WSJ titled [["The Grandmaster’ Review: The 64-Square Universe"|https://www.wsj.com/articles/the-grandmaster-review-the-64-square-universe-1541723866]] by Brad Leithauser he covers a book by Brin-Jonathan Butler, about the current Grand Masters: the Norwegian Magnus Carlsen and Russia’s Sergey Karjakin. Leithauser writes: >A former head of the World Chess Federation, Kirsan Ilyumzhinov, once suggested that the game was a gift to humanity from extraterrestrial visitors. During his lengthy administration (1995-2018), Mr. Ilyumzhinov was accused of many irregularities, including a touch of madness. But his speculation about extraterrestrials seems to me a model of sober levelheadedness. Clearly, the beauty of the game is otherworldly. Like Bach’s “Goldberg Variations” or Vermeer’s interiors or Chartres Cathedral, chess can hardly be the product of a merely human ingenuity. >[...] >Wedded to romantic notions, Mr. Butler loses sight of what is most interesting in the computer’s ascendancy: Chess has become a domain where problem-solving machines impress us not merely with their efficiency and thoroughness but also with their ability to isolate and blazon beauty. They move us aesthetically. The finest chess players can only shake their heads in resigned dazzlement at the loveliness produced by a mechanism that is only executing calculations—that doesn’t in any meaningful sense understand it is playing a game. >[...] >I sympathize with Mr. Butler’s appetite for an “oasis” [i.e., a domain exclusively dominated by humans, not computers] devoted “exclusively [to] the human imagination.” But chess is no longer such a place. I suppose one could repair to poetry or to music—zones where the human spirit might find some restful reflection, free of interlopers. Yet our machines never rest. Even now, perhaps they are concatenating words into lines of verse, arranging musical notes on a staff. Our fellow pilgrims, they likewise are, willy-nilly, chasing beauty. And, I suspect, will be ready to meet us before we’re ready for them. ---- ^^1^^ - Monty Newborn serves as chairman of the ACM Computer Chess Committee, a position he has held since the early 1980s. This committee is in charge of officiating the IBM Kasparov Versus Deep Blue Rematch. Newborn is a professor of computer science at ~McGill University in Montreal. His chess program, OSTRICH, competed in five world championships dating back to the first in 1974. He served as president of the International Computer Chess Association from 1983 to 1986. His research interests center around computer chess and automated theorem proving. Newborn has authored five books on computer chess, the latest being Kasparov versus DEEP BLUE: Computer Chess Comes of Age, published by Springer-Verlag of New York.
I stumbled across this [[insightful and gentle review|https://www.brainpickings.org/2015/01/27/lewis-carroll-letter-writing-email/]] by Maria Popova in ~BrainPickings, of Lewis Carroll's little pamphlet "Eight or Nine Wise Words about ~Letter-Writing" (1890), and found it very relevant and potentially very constructive to our day and age. Most of us have long ago (probably since the 1990's :) abandoned (or never started?) letter writing in favor of emails (if that; some/most moved on to shorter forms of communication, with what I sometimes fear, the ultimate goal/form being communication via grunts :). But while Carroll writes about writing letters, I think that a lot of his "wise advice" still holds, if your aim is to co-respond intelligently, constructively, and kindly. In other words (Popova's :), if your goal is to write >the kind of slow, contemplative correspondence that Virginia Woolf termed “the humane art.” For what more humane an act is there than correspondence itself — the art of mutual response — especially amid a culture of knee-jerk reactions that is the hallmark of most communication today? Letters, by their very nature, make us pause to reflect on what the other person is saying and on what we’d like to say to them in response. Only when we step out of the reactive ego, out of the anxious immediacy that text-messaging and email have instilled in us, and contemplate what is being communicated — only then do we stand a chance of being civil to one another, and maybe even kind. So here are a few wise suggestions from the author of "Alice in Wonderland" and "Through the Looking Glass": * If the Letter is to be in answer to another, begin by getting out that other letter and reading it through, in order to refresh your memory, as to what it is you have to answer… A great deal of the bad writing in the world comes simply from writing too quickly. ** Or, looked at (by the inimitable Daniel Dennett) from a different perspective (in his book [[ Intuition Pumps and Other Tools for Thinking|http://www.openculture.com/2013/05/philosopher_daniel_dennett_presents_seven_tools_for_critical_thinking.html]]), stating "How to compose a successful critical commentary": *** You should attempt to re-express your target’s position so clearly, vividly, and fairly that your target says, “Thanks, I wish I’d thought of putting it that way." *** You should list any points of agreement (especially if they are not matters of general or widespread agreement). *** You should mention anything you have learned from your target. *** Only then are you permitted to say so much as a word of rebuttal or criticism. * When you have written a letter that you feel may possibly irritate your friend, however necessary you may have felt it to so express yourself, put it aside till the next day. Then read it over again, and fancy it addressed to yourself. This will often lead to your writing it all over again, taking out a lot of the vinegar and pepper, and putting in honey instead, and thus making a much more palatable dish of it! ** and, I think, in the same vein, Arthur Martine counseled in his [[magnificent guide to the art of conversation|https://www.brainpickings.org/2013/04/17/the-art-of-conversation-martine-etiquette-1866/]] (1866), “In disputes upon moral or scientific points, let your aim be to come at truth, not to conquer your opponent. So you never shall be at a loss in losing the argument, and gaining a new discovery.” * If your friend makes a severe remark, either leave it unnoticed, or make your reply distinctly less severe: and if he makes a friendly remark, tending towards “making up” the little difference that has arisen between you, let your reply be distinctly more friendly. If, in picking a quarrel, each party declined to go more than three-eighths of the way, and if, in making friends, each was ready to go five-eighths of the way — why, there would be more reconciliations than quarrels! ** My aside: it's interesting to compare this advice to the [[ethical behavior strategy and tit-for-tat|On ethical behavior]] in situations of [[Prisoner's Dilemmas|Summary of the Prisoner’s Dilemma]]. * Don’t try to have the last word! How many a controversy would be nipped in the bud, if each was anxious to let the other have the last word! Never mind how telling a rejoinder you leave unuttered: never mind your friend’s supposing that you are silent from lack of anything to say: let the thing drop, as soon as it is possible without discourtesy: remember “speech is silvern, but silence is golden”! * Don’t repeat yourself. When once you have said your say, fully and clearly, on a certain point, and have failed to convince your friend, drop that subject: to repeat your arguments, all over again, will simply lead to his doing the same; and so you will go on, like a Circulating Decimal. Did you ever know a Circulating Decimal come to an end? [Carroll was a mathematician after all, so I guess he couldn't help it slip out ... :)] * If it should ever occur to you to write, jestingly, in dispraise of your friend, be sure you exaggerate enough to make the jesting obvious: a word spoken in jest, but taken as earnest, may lead to very serious consequences. I have known it to lead to the breaking-off of a friendship.
In [[a presentation with this title|https://docs.google.com/presentation/d/1skkpIGPR81RsnIuth2PjhMkCi1YuODqpLOhEEjXsnXQ/edit#slide=id.g1f3740ba5b_0_268]], Andrew Ko at the University of Washington shares some of his ideas based on Computer Science (CS) Ed-focused research. He makes some [[good observations about teachers and teaching, and summarizes|https://medium.com/bits-and-behavior/how-to-be-a-great-cs-teacher-b8a0a2a3600f]]: * __Everyone can learn [CS], but successful learning is determined by:__ ** Prior knowledge ** Motivation ** Quality of practice * __If students fail to learn it’s because:__ ** Students don’t have the prior knowledge you expected ** They aren’t sufficiently motivated (by you or themselves) ** Your class lacks sufficient high quality practice * __Before you became a teacher (or CS professional):__ ** Someone helped you acquire knowledge ** Someone helped motivate you, give you confidence ** Someone helped you structure your practice ** ''Now that someone is YOU.'' ** If you fail, you’ll be robbing the world of the next you :) * __Learning comes from “deliberate practice”, which consists of four things:__ ** Sustained motivation ** Tasks that build new knowledge from prior knowledge ** Immediate personalized feedback to build correct knowledge ** Repetition of the above ** ''If any of these are missing, learning doesn’t happen.'' * __Teacher motivation:__ ** Many teachers (possibly some of you) don’t believe that all their students can learn (AKA, fixed mindset). ** When teachers have fixed mindsets about their students’ intelligence, students come to believe they can’t learn either, and they stop being motivated. ** You need to adopt a ''growth mindset'' (the belief that intelligence comes largely from deliberate practice, not genetics). And gives some good teaching advice: * __Motivate students:__ ** You have to convince students that they can learn. *** Encourage them *** Prove to them they can learn by giving them practice they can succeed at *** Show them that others also struggle, mitigating imposter syndrome * __Create a motivating context:__ ** You have to show students that the content is relevant to their interests, goals, and identity. *** Learn about and know your students as individuals (e.g., their names, goals, interests) *** Link every concept in class to their interests, goals, identities (e.g., start class with why you’re teaching something, then teach it) * __Assess and build on students' prior knowledge:__ ** Devise homework and other practice that build upon your students’ knowledge ** at the beginning of each class, give a pre-test: *** What concepts in your class do they already know? *** What concepts do you expect them to know, but they don’t? ** Adjust what you teach based on their prior knowledge. * __Individualize learning:__ ** Design practice (e.g., homework, activities) that account for differences in students and their knowledge: ** Give challenge tasks to students with more prior knowledge ** Give extra instruction to students with less prior knowledge * __Scaffold the irrelevant hard parts:__ ** Remove those details or give partial solutions, and slowly take the scaffolding away. ** Base scaffolding on students’ prior knowledge. * __Provide learning-promoting feedback:__ ** Deliberate practice requires detailed, personalized, immediate feedback about what someone did right and wrong in their practice. ** Focus on iterative formative feedback that grows ability through success ** Use summative feedback sparingly; it’s delayed and discouraging ** Immediacy of feedback is critical: the sooner they receive it, the better their learning. ** ''Qualitative is better that quantitative'' because it explains mistakes rather than just signalling them ** Provide feedback on homework as soon as they are submitted, giving detailed qualitative feedback about everything they did right and wrong. ** Incentivize students to show their work so you can critique their work. Don’t just tell them whether they were right or wrong. * __Repeated practice promotes mastery:__ ** Most classes are designed to only allow a student to practice something once ** Design your class so that students can practice something multiple times, across a course, until they master the knowledge ** Don’t just give them one problem to solve, give them multiple isomorphic problems to solve. ** And when they get some of those problems wrong, keep giving them practice until they get it right. * __Teaching is your biggest impact:__ ** Your teaching will definitely change the world, shaping how tens of thousands of people will think, act, and create in the world.
by [[Paul Graham|http://www.paulgraham.com/love.html]] - the founder of [[Y Combinator|http://ycombinator.com/apply.html]].
(found during a wanderful (pun intended) web surfing weekend through [[BrainPickings|http://www.brainpickings.org/index.php/2012/02/27/purpose-work-love/]]
January 2006
To do something well you have to like it. That idea is not exactly novel. We've got it down to four words: "Do what you love." But it's not enough just to tell people that. Doing what you love is complicated.
The very idea is foreign to what most of us learn as kids. When I was a kid, it seemed as if work and fun were opposites by definition. Life had two states: some of the time adults were making you do things, and that was called work; the rest of the time you could do what you wanted, and that was called playing. Occasionally the things adults made you do were fun, just as, occasionally, playing wasn't for example, if you fell and hurt yourself. But except for these few anomalous cases, work was pretty much defined as not-fun.
And it did not seem to be an accident. School, it was implied, was tedious because it was preparation for grownup work.
The world then was divided into two groups, grownups and kids. Grownups, like some kind of cursed race, had to work. Kids didn't, but they did have to go to school, which was a dilute version of work meant to prepare us for the real thing. Much as we disliked school, the grownups all agreed that grownup work was worse, and that we had it easy.
Teachers in particular all seemed to believe implicitly that work was not fun. Which is not surprising: work wasn't fun for most of them. Why did we have to memorize state capitals instead of playing dodgeball? For the same reason they had to watch over a bunch of kids instead of lying on a beach. You couldn't just do what you wanted.
I'm not saying we should let little kids do whatever they want. They may have to be made to work on certain things. But if we make kids work on dull stuff, it might be wise to tell them that tediousness is not the defining quality of work, and indeed that the reason they have to work on dull stuff now is so they can work on more interesting stuff later. [1]
Once, when I was about 9 or 10, my father told me I could be whatever I wanted when I grew up, so long as I enjoyed it. I remember that precisely because it seemed so anomalous. It was like being told to use dry water. Whatever I thought he meant, I didn't think he meant work could literally be fun fun like playing. It took me years to grasp that.
''Jobs''
By high school, the prospect of an actual job was on the horizon. Adults would sometimes come to speak to us about their work, or we would go to see them at work. It was always understood that they enjoyed what they did. In retrospect I think one may have: the private jet pilot. But I don't think the bank manager really did.
The main reason they all acted as if they enjoyed their work was presumably the upper-middle class convention that you're supposed to. It would not merely be bad for your career to say that you despised your job, but a social faux-pas.
Why is it conventional to pretend to like what you do? The first sentence of this essay explains that. If you have to like something to do it well, then the most successful people will all like what they do. That's where the upper-middle class tradition comes from. Just as houses all over America are full of chairs that are, without the owners even knowing it, nth-degree imitations of chairs designed 250 years ago for French kings, conventional attitudes about work are, without the owners even knowing it, nth-degree imitations of the attitudes of people who've done great things.
What a recipe for alienation. By the time they reach an age to think about what they'd like to do, most kids have been thoroughly misled about the idea of loving one's work. School has trained them to regard work as an unpleasant duty. Having a job is said to be even more onerous than schoolwork. And yet all the adults claim to like what they do. You can't blame kids for thinking "I am not like these people; I am not suited to this world."
Actually they've been told three lies: the stuff they've been taught to regard as work in school is not real work; grownup work is not (necessarily) worse than schoolwork; and many of the adults around them are lying when they say they like what they do.
The most dangerous liars can be the kids' own parents. If you take a boring job to give your family a high standard of living, as so many people do, you risk infecting your kids with the idea that work is boring. [2] Maybe it would be better for kids in this one case if parents were not so unselfish. A parent who set an example of loving their work might help their kids more than an expensive house. [3]
It was not till I was in college that the idea of work finally broke free from the idea of making a living. Then the important question became not how to make money, but what to work on. Ideally these coincided, but some spectacular boundary cases (like Einstein in the patent office) proved they weren't identical.
The definition of work was now to make some original contribution to the world, and in the process not to starve. But after the habit of so many years my idea of work still included a large component of pain. Work still seemed to require discipline, because only hard problems yielded grand results, and hard problems couldn't literally be fun. Surely one had to force oneself to work on them.
If you think something's supposed to hurt, you're less likely to notice if you're doing it wrong. That about sums up my experience of graduate school.
''Bounds''
How much are you supposed to like what you do? Unless you know that, you don't know when to stop searching. And if, like most people, you underestimate it, you'll tend to stop searching too early. You'll end up doing something chosen for you by your parents, or the desire to make money, or prestige or sheer inertia.
Here's an upper bound: Do what you love doesn't mean, do what you would like to do most this second. Even Einstein probably had moments when he wanted to have a cup of coffee, but told himself he ought to finish what he was working on first.
It used to perplex me when I read about people who liked what they did so much that there was nothing they'd rather do. There didn't seem to be any sort of work I liked that much. If I had a choice of (a) spending the next hour working on something or (b) be teleported to Rome and spend the next hour wandering about, was there any sort of work I'd prefer? Honestly, no.
But the fact is, almost anyone would rather, at any given moment, float about in the Carribbean, or have sex, or eat some delicious food, than work on hard problems. The rule about doing what you love assumes a certain length of time. It doesn't mean, do what will make you happiest this second, but what will make you happiest over some longer period, like a week or a month.
Unproductive pleasures pall eventually. After a while you get tired of lying on the beach. If you want to stay happy, you have to do something.
As a lower bound, you have to like your work more than any unproductive pleasure. You have to like what you do enough that the concept of "spare time" seems mistaken. Which is not to say you have to spend all your time working. You can only work so much before you get tired and start to screw up. Then you want to do something else even something mindless. But you don't regard this time as the prize and the time you spend working as the pain you endure to earn it.
I put the lower bound there for practical reasons. If your work is not your favorite thing to do, you'll have terrible problems with procrastination. You'll have to force yourself to work, and when you resort to that the results are distinctly inferior.
To be happy I think you have to be doing something you not only enjoy, but admire. You have to be able to say, at the end, wow, that's pretty cool. This doesn't mean you have to make something. If you learn how to hang glide, or to speak a foreign language fluently, that will be enough to make you say, for a while at least, wow, that's pretty cool. What there has to be is a test.
So one thing that falls just short of the standard, I think, is reading books. Except for some books in math and the hard sciences, there's no test of how well you've read a book, and that's why merely reading books doesn't quite feel like work. You have to do something with what you've read to feel productive.
I think the best test is one Gino Lee taught me: to try to do things that would make your friends say wow. But it probably wouldn't start to work properly till about age 22, because most people haven't had a big enough sample to pick friends from before then.
''Sirens''
What you should not do, I think, is worry about the opinion of anyone beyond your friends. You shouldn't worry about prestige. Prestige is the opinion of the rest of the world. When you can ask the opinions of people whose judgement you respect, what does it add to consider the opinions of people you don't even know? [4]
This is easy advice to give. It's hard to follow, especially when you're young. [5] Prestige is like a powerful magnet that warps even your beliefs about what you enjoy. It causes you to work not on what you like, but what you'd like to like.
That's what leads people to try to write novels, for example. They like reading novels. They notice that people who write them win Nobel prizes. What could be more wonderful, they think, than to be a novelist? But liking the idea of being a novelist is not enough; you have to like the actual work of novel-writing if you're going to be good at it; you have to like making up elaborate lies.
Prestige is just fossilized inspiration. If you do anything well enough, you'll make it prestigious. Plenty of things we now consider prestigious were anything but at first. Jazz comes to mind though almost any established art form would do. So just do what you like, and let prestige take care of itself.
Prestige is especially dangerous to the ambitious. If you want to make ambitious people waste their time on errands, the way to do it is to bait the hook with prestige. That's the recipe for getting people to give talks, write forewords, serve on committees, be department heads, and so on. It might be a good rule simply to avoid any prestigious task. If it didn't suck, they wouldn't have had to make it prestigious.
Similarly, if you admire two kinds of work equally, but one is more prestigious, you should probably choose the other. Your opinions about what's admirable are always going to be slightly influenced by prestige, so if the two seem equal to you, you probably have more genuine admiration for the less prestigious one.
The other big force leading people astray is money. Money by itself is not that dangerous. When something pays well but is regarded with contempt, like telemarketing, or prostitution, or personal injury litigation, ambitious people aren't tempted by it. That kind of work ends up being done by people who are "just trying to make a living." (Tip: avoid any field whose practitioners say this.) The danger is when money is combined with prestige, as in, say, corporate law, or medicine. A comparatively safe and prosperous career with some automatic baseline prestige is dangerously tempting to someone young, who hasn't thought much about what they really like.
The test of whether people love what they do is whether they'd do it even if they weren't paid for it even if they had to work at another job to make a living. How many corporate lawyers would do their current work if they had to do it for free, in their spare time, and take day jobs as waiters to support themselves?
This test is especially helpful in deciding between different kinds of academic work, because fields vary greatly in this respect. Most good mathematicians would work on math even if there were no jobs as math professors, whereas in the departments at the other end of the spectrum, the availability of teaching jobs is the driver: people would rather be English professors than work in ad agencies, and publishing papers is the way you compete for such jobs. Math would happen without math departments, but it is the existence of English majors, and therefore jobs teaching them, that calls into being all those thousands of dreary papers about gender and identity in the novels of Conrad. No one does that kind of thing for fun.
The advice of parents will tend to err on the side of money. It seems safe to say there are more undergrads who want to be novelists and whose parents want them to be doctors than who want to be doctors and whose parents want them to be novelists. The kids think their parents are "materialistic." Not necessarily. All parents tend to be more conservative for their kids than they would for themselves, simply because, as parents, they share risks more than rewards. If your eight year old son decides to climb a tall tree, or your teenage daughter decides to date the local bad boy, you won't get a share in the excitement, but if your son falls, or your daughter gets pregnant, you'll have to deal with the consequences.
''Discipline''
With such powerful forces leading us astray, it's not surprising we find it so hard to discover what we like to work on. Most people are doomed in childhood by accepting the axiom that work = pain. Those who escape this are nearly all lured onto the rocks by prestige or money. How many even discover something they love to work on? A few hundred thousand, perhaps, out of billions.
It's hard to find work you love; it must be, if so few do. So don't underestimate this task. And don't feel bad if you haven't succeeded yet. In fact, if you admit to yourself that you're discontented, you're a step ahead of most people, who are still in denial. If you're surrounded by colleagues who claim to enjoy work that you find contemptible, odds are they're lying to themselves. Not necessarily, but probably.
Although doing great work takes less discipline than people think because the way to do great work is to find something you like so much that you don't have to force yourself to do it finding work you love does usually require discipline. Some people are lucky enough to know what they want to do when they're 12, and just glide along as if they were on railroad tracks. But this seems the exception. More often people who do great things have careers with the trajectory of a ping-pong ball. They go to school to study A, drop out and get a job doing B, and then become famous for C after taking it up on the side.
Sometimes jumping from one sort of work to another is a sign of energy, and sometimes it's a sign of laziness. Are you dropping out, or boldly carving a new path? You often can't tell yourself. Plenty of people who will later do great things seem to be disappointments early on, when they're trying to find their niche.
Is there some test you can use to keep yourself honest? One is to try to do a good job at whatever you're doing, even if you don't like it. Then at least you'll know you're not using dissatisfaction as an excuse for being lazy. Perhaps more importantly, you'll get into the habit of doing things well.
Another test you can use is: always produce. For example, if you have a day job you don't take seriously because you plan to be a novelist, are you producing? Are you writing pages of fiction, however bad? As long as you're producing, you'll know you're not merely using the hazy vision of the grand novel you plan to write one day as an opiate. The view of it will be obstructed by the all too palpably flawed one you're actually writing.
"Always produce" is also a heuristic for finding the work you love. If you subject yourself to that constraint, it will automatically push you away from things you think you're supposed to work on, toward things you actually like. "Always produce" will discover your life's work the way water, with the aid of gravity, finds the hole in your roof.
Of course, figuring out what you like to work on doesn't mean you get to work on it. That's a separate question. And if you're ambitious you have to keep them separate: you have to make a conscious effort to keep your ideas about what you want from being contaminated by what seems possible. [6]
It's painful to keep them apart, because it's painful to observe the gap between them. So most people pre-emptively lower their expectations. For example, if you asked random people on the street if they'd like to be able to draw like Leonardo, you'd find most would say something like "Oh, I can't draw." This is more a statement of intention than fact; it means, I'm not going to try. Because the fact is, if you took a random person off the street and somehow got them to work as hard as they possibly could at drawing for the next twenty years, they'd get surprisingly far. But it would require a great moral effort; it would mean staring failure in the eye every day for years. And so to protect themselves people say "I can't."
Another related line you often hear is that not everyone can do work they love that someone has to do the unpleasant jobs. Really? How do you make them? In the US the only mechanism for forcing people to do unpleasant jobs is the draft, and that hasn't been invoked for over 30 years. All we can do is encourage people to do unpleasant work, with money and prestige.
If there's something people still won't do, it seems as if society just has to make do without. That's what happened with domestic servants. For millennia that was the canonical example of a job "someone had to do." And yet in the mid twentieth century servants practically disappeared in rich countries, and the rich have just had to do without.
So while there may be some things someone has to do, there's a good chance anyone saying that about any particular job is mistaken. Most unpleasant jobs would either get automated or go undone if no one were willing to do them.
''Two Routes''
There's another sense of "not everyone can do work they love" that's all too true, however. One has to make a living, and it's hard to get paid for doing work you love. There are two routes to that destination:
The organic route: as you become more eminent, gradually to increase the parts of your job that you like at the expense of those you don't.
The two-job route: to work at things you don't like to get money to work on things you do.
The organic route is more common. It happens naturally to anyone who does good work. A young architect has to take whatever work he can get, but if he does well he'll gradually be in a position to pick and choose among projects. The disadvantage of this route is that it's slow and uncertain. Even tenure is not real freedom.
The two-job route has several variants depending on how long you work for money at a time. At one extreme is the "day job," where you work regular hours at one job to make money, and work on what you love in your spare time. At the other extreme you work at something till you make enough not to have to work for money again.
The two-job route is less common than the organic route, because it requires a deliberate choice. It's also more dangerous. Life tends to get more expensive as you get older, so it's easy to get sucked into working longer than you expected at the money job. Worse still, anything you work on changes you. If you work too long on tedious stuff, it will rot your brain. And the best paying jobs are most dangerous, because they require your full attention.
The advantage of the two-job route is that it lets you jump over obstacles. The landscape of possible jobs isn't flat; there are walls of varying heights between different kinds of work. [7] The trick of maximizing the parts of your job that you like can get you from architecture to product design, but not, probably, to music. If you make money doing one thing and then work on another, you have more freedom of choice.
Which route should you take? That depends on how sure you are of what you want to do, how good you are at taking orders, how much risk you can stand, and the odds that anyone will pay (in your lifetime) for what you want to do. If you're sure of the general area you want to work in and it's something people are likely to pay you for, then you should probably take the organic route. But if you don't know what you want to work on, or don't like to take orders, you may want to take the two-job route, if you can stand the risk.
Don't decide too soon. Kids who know early what they want to do seem impressive, as if they got the answer to some math question before the other kids. They have an answer, certainly, but odds are it's wrong.
A friend of mine who is a quite successful doctor complains constantly about her job. When people applying to medical school ask her for advice, she wants to shake them and yell "Don't do it!" (But she never does.) How did she get into this fix? In high school she already wanted to be a doctor. And she is so ambitious and determined that she overcame every obstacle along the way including, unfortunately, not liking it.
Now she has a life chosen for her by a high-school kid.
When you're young, you're given the impression that you'll get enough information to make each choice before you need to make it. But this is certainly not so with work. When you're deciding what to do, you have to operate on ridiculously incomplete information. Even in college you get little idea what various types of work are like. At best you may have a couple internships, but not all jobs offer internships, and those that do don't teach you much more about the work than being a batboy teaches you about playing baseball.
In the design of lives, as in the design of most other things, you get better results if you use flexible media. So unless you're fairly sure what you want to do, your best bet may be to choose a type of work that could turn into either an organic or two-job career. That was probably part of the reason I chose computers. You can be a professor, or make a lot of money, or morph it into any number of other kinds of work.
It's also wise, early on, to seek jobs that let you do many different things, so you can learn faster what various kinds of work are like. Conversely, the extreme version of the two-job route is dangerous because it teaches you so little about what you like. If you work hard at being a bond trader for ten years, thinking that you'll quit and write novels when you have enough money, what happens when you quit and then discover that you don't actually like writing novels?
Most people would say, I'd take that problem. Give me a million dollars and I'll figure out what to do. But it's harder than it looks. Constraints give your life shape. Remove them and most people have no idea what to do: look at what happens to those who win lotteries or inherit money. Much as everyone thinks they want financial security, the happiest people are not those who have it, but those who like what they do. So a plan that promises freedom at the expense of knowing what to do with it may not be as good as it seems.
Whichever route you take, expect a struggle. Finding work you love is very difficult. Most people fail. Even if you succeed, it's rare to be free to work on what you want till your thirties or forties. But if you have the destination in sight you'll be more likely to arrive at it. If you know you can love work, you're in the home stretch, and if you know what work you love, you're practically there.
----
Notes
[1] Currently we do the opposite: when we make kids do boring work, like arithmetic drills, instead of admitting frankly that it's boring, we try to disguise it with superficial decorations.
[2] One father told me about a related phenomenon: he found himself concealing from his family how much he liked his work. When he wanted to go to work on a saturday, he found it easier to say that it was because he "had to" for some reason, rather than admitting he preferred to work than stay home with them.
[3] Something similar happens with suburbs. Parents move to suburbs to raise their kids in a safe environment, but suburbs are so dull and artificial that by the time they're fifteen the kids are convinced the whole world is boring.
[4] I'm not saying friends should be the only audience for your work. The more people you can help, the better. But friends should be your compass.
[5] Donald Hall said young would-be poets were mistaken to be so obsessed with being published. But you can imagine what it would do for a 24 year old to get a poem published in The New Yorker. Now to people he meets at parties he's a real poet. Actually he's no better or worse than he was before, but to a clueless audience like that, the approval of an official authority makes all the difference. So it's a harder problem than Hall realizes. The reason the young care so much about prestige is that the people they want to impress are not very discerning.
[6] This is isomorphic to the principle that you should prevent your beliefs about how things are from being contaminated by how you wish they were. Most people let them mix pretty promiscuously. The continuing popularity of religion is the most visible index of that.
[7] A more accurate metaphor would be to say that the graph of jobs is not very well connected.
Thanks to Trevor Blackwell, Dan Friedman, Sarah Harlin, Jessica Livingston, Jackie McDonough, Robert Morris, Peter Norvig, David Sloo, and Aaron Swartz for reading drafts of this.
In a no-nonsense, [[straight-talk article|http://ww2.kqed.org/mindshift/2015/04/09/how-memory-focus-and-good-teaching-can-work-together-to-help-kids-learn/]] in [[KQED's Mind/Shift section|http://ww2.kqed.org/mindshift/about/]] titled //How Memory, Focus and Good Teaching Can Work Together to Help Kids Learn//, journalist Katrina Schwartz talked with William Klemm, a senior professor of neuroscience at Texas A&M University, about his ideas for improving how kids learn: focus on teaching kids how to learn. Klemm claims that >The more you teach students how to learn, the less time you have to spend teaching curriculum because they can [understand] it on their own, [...] I think the real problem is that students have not learned how to be competent learners. They haven’t learned this because we haven’t taught them. He mentioned a few things that are fairly well researched and could help improve learning, but are often not practiced in schools: * Using the internet for researching topics and finding information is great for learning, because if provides easy access to both more depth and more breadth of information and resources. This potentially improves knowledge and understanding, because the more connections learners can make, and the more relevant and applicable context they have, the better the understanding and the deeper the knowledge. But, using the internet usually exposes the learner to many more distractions and disruptions, and this is really bad for learning. Klemm said: >When this happens, kids multitask, a concept neuroscientists have shown doesn’t really exist. When a person thinks she is doing two things at once, she is really switching rapidly back and forth between individual tasks, eroding the attention and quality of each task in the process. Learners (and teachers and schools) should actively seek to avoid or minimize distractions. * Another negative effect of relying too much on the internet, to the point where learners delegate the memorization of knowledge and facts to it, rather than committing it to their memories, is that ** without knowledge in your head, it's harder to acquire ''new'' knowledge, since there is less of a richer context in your head. ** also, with less memorized knowledge, it takes longer to process and store new information, so this may create a "snowball" effect in reduced learning. ** students are also less likely to ask new, informed, deep questions, if they don't have more knowledge/information/facts in their heads, which impacts learning even more. In Klemm's words: >The more you know, the more you can make conclusions, even be creative,” Klemm said. “All of these things have to be done by thinking, and thinking has to be done from what’s in your working memory. * When people "multitask" it disrupts and interferes with the forming of memories. Teaching learners to focus is a critical skill to have. Minimizing distractions is critical, --before, during, and after-- learning new knowledge or skill. ** Right after learning something new, the brain needs some time and focus for processing that knowledge and committing it to long term memory (“Long-term memory requires physical and chemical changes in the brain”). Distracting the learner right after learning something new disrupts the process of forming long term memories of the knowledge. * Stress is bad for learning. >When students are worried about tests or something in their private lives, they are distracted from what’s going on in the classroom. * Testing should be done for a reason, and it is a good thing if it’s non-punitive. Tests require students to recall what they know and process what they don’t know. But high stakes tests, while sometimes necessary, can, and are often overdone. * Teachers and schools should teach more learning skills, like memorization techniques, visualizations, and modeling. >If they knew these things, they wouldn’t have to work so hard and school might even become fun. Once students start reflecting and become more self-aware, they have the opportunity to become better students.
In an excellent book titled [["When Einstein Walked with Gödel -- Excursions to the Edge of Thought"|https://www.nytimes.com/2018/05/15/books/review/review-when-einstein-walked-with-godel-jim-holt.html]]^^1^^, Jim Holt asks the question: "which, from the point of view of the universe, is more contemptible -- our minuteness (in terms of size) or our brevity (in terms of lifespan)?" <a href="resources/resources/human scale 1.png" target="new"><img src="resources/human scale 1.png" width="90%" height="90%" /></a> >Now, suppose we construct two cosmic scales, one for size and one for longevity. The size scale will extend from the smallest the Planck length [10^^-35^^ meters], to the largest possible size, the radius of the observable universe [~10^^26^^ meters]. The longevity scale will extend from the briefest possible life span, the Planck time [10^^-43^^ seconds], to the longest possible life span, the current age of the universe [~10^^10^^ years]. > >Where do we rank on these two scales? On the cosmic size scale humans, at a meter or two in length, are more or less in the middle. Roughly speaking, the observable universe dwarfs us the way we dwarf the Planck length. On the longevity scale, by contrast, we are very close to the top. The number of Planck times that make up a human lifetime is very, very much more than the number of human lifetimes that make up the age of the universe. “People talk about the ephemeral nature of existence," the physicist Roger Penrose has commented. “but [on such a scale] it can be seen that we are not ephemeral at all -- we live more or less as long as the Universe itself!" > >Certainly, then, we humans have little reason to feel angst about our temporal finitude. Sub specie aeternitatis [viewed in relation to the eternal], we endure for an awfully long time. But our extreme puniness certainly gives us cause for cosmic embarrassment. ---- ^^1^^ - searchable spelling: Gödel, Godel, Goedel.
<<list-links "[tag[epss-item]]">>
Believe it or not (and you definitely will, if you know the guy ;-), Douglas Hofstadter conducted a [[Workshop on Humor and Cognition|http://arxiv.org/ftp/arxiv/papers/1310/1310.1676.pdf]] in 1989, where he outlines the structure of certain jokes in terms of "cognitive frames" as implemented in [[Copycat|http://cognitrn.psych.indiana.edu/rgoldsto/courses/concepts/copycat.pdf]], an intelligent software program created by his group at the Indiana University. The motivation for this workshop: >The Workshop on Humor and Cognition was therefore motivated to a large extent by the observation that jokes have much in common with analogies gone awry, and by the belief that through exploration of the similarities and differences between humor and analogy, we would sharpen our understanding of both processes, and of the fluid nature of human thought in general. Hofstadter and his group have been trying to understand intelligence and cognition by creating very simple, stripped down domains, and building software that would behave intelligently within these areas (somewhat similar (analogous? ;-) to [[Terry Winograd's SHRDLU program|http://hci.stanford.edu/~winograd/shrdlu/]]). One example of this is the following problem in Copycat's domain: >If the string abc is changed to abd, how can one change ijk "the same way"? and Hofstadter continues: >In this particular problem, most people view the initial event as "replacement of the rightmost letter by its successor". Straightforward application of this rule to the target string ijk yields ijl. It would be possible, nonetheless, to take the change much more literally — namely, as "replacement of the rightmost letter by d" — and thus to answer ijd. Few people see this as a better answer than ijl — in fact, few people even think of it at all. And the relation to humor? >The answer ijd is a simple frame blend, in which the abc/abd frame contributes just one element — the d to the ijk frame. Seen this way, this answer to the problem bears a strong similarity to the following well-known joke: >American: Look how free we are in America — nobody prevents us from parading in front of the White House and yelling, "Down with Reagan!" >Russian: We in Russia are just as free as you — nobody prevents us from parading in front of the Kremlin and yelling, "Down with Reagan!" >Here, the Russian attempts to "translate" the notion of free speech from an American to a Soviet frame, but instead of carrying it fully across (as would happen in a good analogy), blurs frames by importing Reagan literally into the Soviet frame. Thus a bad analogy, in the form of a frame blend, makes for a good joke. Hofstadter, again, in a thinking and writing style that is clear, down-to-earth, and very plausible, explains a mechanism for understanding and possibly creating/engineering humor. As I had said, jokes are serious business.
A couple of weeks ago I had the opportunity (actually, the necessity, since I was asked) to explain to a parent of one of the students why I am OK with a "heightened level of energy" in my CS classroom, and I had said: >The atmosphere in my class is usually somewhat informal, and I don't mind some "heightened energy" in my class, since I believe that some excitement and a sense of fun are enhancing learning and are usually motivators and enablers of creativity and experimentation in a safe environment, where trying (and sometimes failing) is OK, as long as we learn from our actions. A couple of days later, I came across an article in the WSJ titled [["Astro Teller, Captain of Moonshots"|http://www.wsj.com/articles/astro-teller-captain-of-moonshots-1479491399]], the head of Alphabet's X organization (Google's top R&D group) (Dr. Astro Teller is the grandchild of the physicist Edward Teller, who helped to develop the hydrogen bomb). The author of the article, Alexandra Wolff, wrote: >“I certainly encourage low deference to authority here,” he says. “Humor and creativity are inexorably linked. It’s very hard to be sad or serious…and to come up with really different perspectives.” He believes that the sillier, happier and more naturally childlike people are, the more they are able to shift perspectives and come up with innovative ideas. It is not my intention to run my classes as startups (even if we are in the middle of Silicon Valley :), but it was nice to see the affirmation that some playfulness fosters creativity, which is one of the [["Big Ideas" (in CS)|https://advancesinap.collegeboard.org/stem/computer-science-principles/course-details]] I am constantly trying to get across to students.
I am always ready to learn although I do not always like being taught.
[[Richard Feynman]] [[captured on video|https://www.youtube.com/watch?v=QkhBcLk_8f0]] >You see, one thing is, I can live with doubt and uncertainty and not knowing^^1^^. I think it's much more interesting to live not knowing than to have answers which might be wrong. I have approximate answers and possible beliefs and different degrees of certainty about different things, but I am not absolutely sure of anything and there are many things I do not know anything about, such as whether it means anything to ask 'why we are here?' and what the question might mean. I might think about it a little bit if I can figure it out then I go into something else. But I don't have to know an answer. I don't have ... I don't feel frightened by not knowing things, by being lost in a mysterious universe without having any purpose, which is the way it really is as far as I can tell, possibly. It doesn't frighten me. ---- ^^1^^ - and according to Terry Pratchett, [[even DEATH can try to believe in it|THE UNCERTAINTY PRINICIPLE - according to Sir Terry]]
not really. One of the projects I have my high school Computer Science students do is write a music composition piece using [[EarSketch|http://earsketch.gatech.edu/earsketch2/]] (developed at Georgia Tech). This tool enables them to create different pieces of music programmatically. Since it's part of a CS course, I'm not looking at the "artistic/musical value/talent" but rather at the programming language (Python) techniques of the students. So as I was listening to student compositions/projects, I came across 2 pieces which //looked// similar. Mind you, I'm listening to the compositions, but am also looking at the code, and I had a strong suspicion that one of the students copied from the other. The students did a good job of picking different instruments, etc., for their pieces, so that on the surface, the compositions sounded different enough. But the underlying structure was almost identical: |[img[EarSketch 1|./resources/M_Final_Earsketch_small.png][./resources/M_Final_Earsketch.png]]|[img[EarSketch 2|./resources/V_Final_Earsketch_small.png][./resources/V_Final_Earsketch.png]]| As you can see from the above, the structure and the code (except for the musical instruments) look identical. If this is not a case of plagiarism and direct copying, then I don't know what is. So, I don't have a "super ear" but more of a "sharp eye", but the students are definitely in trouble. I am surprised that they thought that in a computer programming project I will only listen to the music and not look at the code... Regardless, I still strongly believe that [[letting and encouraging students to look at other people's code|Should students be able to look at each other's code?]] is an excellent way to learn programming, so I'll keep doing that. I just need to be stronger on the message of "no plagiarism".
"I have made this longer than usual because I have not had time to make it shorter." - Translated from French:
Je n’ai fait celle-ci plus longue que parce que je n’ai pas eu le loisir de la faire plus courte.
- from the [[Quote Investigator|https://quoteinvestigator.com/2012/04/28/shorter-letter/]], who is also retelling the following:
>According to an anecdote published in 1918, Woodrow Wilson was asked about the amount of time he spent preparing speeches, and his response was illuminating:
>> "That depends on the length of the speech," answered the President. "If it is a ten-minute speech, it takes me all of two weeks to prepare it; if it is a half-hour speech, it takes me a week; if I can talk as long as I want to, it requires no preparation at all. I am ready now."
I have never developed indigestion from eating my words.
I'll understand quickly if you explain slowly.
At least in business and entrepreneurship (among other areas?^^1^^), [[Ideas are just a multiplier of execution - from Derek Sivers|https://sivers.org/multiply]] !!!!So here's how Sivers (succinctly) puts it: It’s so funny when I hear people being so protective of ideas. People who want me to sign an NDA to tell me the simplest idea. To me, ideas are worth nothing unless executed. They are just a multiplier. Execution is worth millions. Explanation: AWFUL IDEA = -1 WEAK IDEA = 1 SO-SO IDEA = 5 GOOD IDEA = 10 GREAT IDEA = 15 BRILLIANT IDEA = 20 -------- --------- NO EXECUTION = $1 WEAK EXECUTION = $1000 ~SO-SO EXECUTION = $10,000 GOOD EXECUTION = $100,000 GREAT EXECUTION = $1,000,000 BRILLIANT EXECUTION = $10,000,000 To make a business, you need to multiply the two. The most brilliant idea, with no execution, is worth $20. The most brilliant idea takes great execution to be worth $20,000,000. ---- ^^1^^ - an interesting question is whether this idea (ha) is extensible to other areas in life. For example, to politics, where as Winston Churchill famously said about ideas/ideals vs. execution/results: >"It is a fine thing to be honest, but it is also very important to be right". Or another (somewhat freely interpreted Churchill pearl (as you can probably tell, I think that there is a lot to admire about him :) >"It's not enough that we do [or think/aspire to] our best; sometimes we have to do what's required."
In a thought-provoking presentation titled [["If Copernicus and Kepler Had Computers"|http://www.cs.cornell.edu/cv/OtherPdf/Copern.pdf]], Cornell University Computer Science professor [[Charles Van Loan|http://www.cs.cornell.edu/cv/default.htm]] quotes^^1^^ an interesting hypothesis by another computer scientist -- Abbe Mowshowitz:
>If a computer had been available to Copernicus, he would have been content to patch up the Ptolemaic system rather than propose a new model of the cosmos.
Van Loan shows by example, how the Ancients tried to explain the fact that the planets (the presentation specifically covers Mars) "wander" or "wobble" in their orbit in the sky. Since the prevailing "standard model" at the time was geocentric, the Ancients tried to fit this observed planetary behavior with a model made of multiple circles rotating along the orbits of other circles.
(see [[Python simulation program below|https://trinket.io/python/6d4f189f98?runOption=run]])
<html>
<table>
<tr>
<td><img src='resources/mars wanders.png'><p>Mars wanders</td>
<td><img src='resources/Python program.png'><p><a href='https://trinket.io/python/6d4f189f98?runOption=run'>Python simulation program</a></td>
</tr>
<tr>
<td><img src='resources/mars 1 circle.png'><p>Mars 1 circle model</td>
<td><img src='resources/Mars 1 circle path.png'><p>Mars 1 circle path</td>
</tr>
<tr>
<td><img src='resources/mars 2 circles.png'><p>Mars 2 circle model</td>
<td><img src='resources/Mars 2 circle path.png'><p>Mars 2 circle path</td>
</tr>
</table>
</html>
So the question is:
>If Copernicus had a computer would he have been content to patch up the Ptolemaic model by adding more circles on circles until the model fit the data with sufficient accuracy?
It turns out that a model/simulation made of 9 circles (!), with different radii and rotation periods can fit the actual observed orbit of Mars with less than a 5 minute of arc error. Impressive! But very complex, and begging for the application of [[Occam's Razor|https://en.wikipedia.org/wiki/Occam%27s_razor]] ("one should not increase, beyond what is necessary, the number of entities required to explain anything").
And the conclusion:
The Computer can make us lazy because it is tempting to “tweak the old model”
But,
The Computer can make us creative because it enables us to “think outside the box”
----
^^1^^ I love Van Loan's quote [[Formalism First = Rigor Mortis. Intuition First = Rigor's Mortise]].
From ~BrainPickings [[The Accidental Uniiverse|https://www.brainpickings.org/2014/02/04/accidental-universe-alan-lightman/]]: >On one thing most physicists agree. If the amount of dark energy in our universe were only a little bit different than what it actually is, then life could never have emerged. A little larger, and the universe would have accelerated so rapidly that matter in the young universe could never have pulled itself together to form stars and hence complex atoms made in stars. And, going into negative values of dark energy, a little smaller and the universe would have decelerated so rapidly that it would have recollapsed before there was time to form even the simplest atoms. >Out of all the possible amounts of dark energy that our universe might have, the actual amount lies in the tiny sliver of the range that allows life. There is little argument on this point. It does not depend on assumptions about whether we need liquid water for life or oxygen or particular biochemistries. It depends only on the requirement of atoms. As before, one is compelled to ask the question: Why does such fine-tuning occur? And the answer many physicists now believe: the multiverse. A vast number of universes may exist, with many different values of the amount of dark energy. Our particular universe is one of the universes with a small value, permitting the emergence of life. We are here, so our universe must be such a universe. We are an accident. From the cosmic lottery hat containing zillions of universes, we happened to draw a universe that allowed life. But then again, if we had not drawn such a ticket, we would not be here to ponder the odds. > If the multiverse idea is correct, then the historic mission of physics to explain all the properties of our universe in terms of fundamental principles — to explain why the properties of our universe must necessarily be what they are — is futile, a beautiful philosophical dream that simply isn’t true. Our universe is what it is simply because we are here. The situation can be likened to that of a group of intelligent fish who one day begin wondering why their world is completely filled with water. Many of the fish, the theorists, hope to prove that the cosmos necessarily has to be filled with water. For years, they put their minds to the task but can never quite seem to prove their assertion. Then a wizened group of fish postulates that maybe they are fooling themselves. Maybe, they suggest, there are many other worlds, some of them completely dry, some wet, and everything in between.
From the man himself: >My late Uncle Alex Vonnegut […] who was well read and wise, was a humanist like the rest of the family. What Uncle Alex found particularly objectionable about human beings in general, was that they so seldom noticed it when they were happy. >He himself did his best to acknowledge it when times were sweet. We could be drinking lemonade in the shade of an apple tree in the summertime, and Uncle Alex would interrupt the conversation to say, “If this isn’t nice, what is?” >I myself say that out loud at times of easy, natural bliss: “If this isn’t nice, what is?” Perhaps others can also make use of that heirloom from Uncle Alex. I find it really cheers me up to keep score out loud that way. -- Kurt Vonnegut (compared with [[Danial Dennett's sentiment|Thanks Goodness!]])
If we open a quarrel between past and present, we shall find that we have lost the future.
If you have ten thousand regulations you destroy all respect for the law.
If you have to have a policy manual, publish the Ten Commandments. on corporate management style, and procedure manuals, from the book [[Up The Organization|http://www.amazon.com/gp/product/0787987751?ie=UTF8&isInIframe=1&n=283155&redirect=true&ref_=dp_proddesc_0&s=books&showDetailProductDesc=1#iframe-wrapper]] (originally published in 1970)
In his excellent book^^1^^ [[Probably Approximately Correct|http://www.probablyapproximatelycorrect.com/]], Leslie Valiant tells the following story: in 1947 John von Neumann, the famously gifted mathematician, was keynote speaker at the first annual meeting of the Association for Computing Machinery. In his address he said that future computers would get along with just a dozen instruction types, a number known to be adequate for expressing all of mathematics. He went on to say that one need not be surprised at this small number, since 1,000 words were known to be adequate for most situations in real life, and mathematics was only a small part of life, and a very simple part at that. The audience reacted with hilarity. This provoked von Neumann to respond: “If people do not believe that math is simple, it is only because they do not realize how complicated life is.” ---- ^^1^^ - see the [[book remarks|Ecorithms - Probably Approximately Correct Algorithms - by Leslie Valiant]]
If you're as clever as you can be when you write it, how will you ever debug it?
In his delightful book [[An Imaginary Tale|http://www.pucrs.br/famat/viali/tic_literatura/livros/Paul%20J.%20Nahin%20-%20An%20Imaginary%20Tale%20The%20Story%20of%20i%20the%20Square%20Root%20of%20Minus%20One.pdf]] - The Story of [img[square root of -1|./resources/i 1.png][./resources/i.png]], Paul J. Nahin has the following Calvin and Hobbs cartoon: [img[complex math|./resources/CalvinHobbesImaginary.gif]] In the preface Nahin tells the following story: >When the April 1955 issue of Popular Electronics arrived in the mail, one of the inside photographs displayed an incredible sight a desk lamp emitting not a cone of light, but, instead, a ''cone of darkness''! My eyes bugged out when I saw that. What wondrous science was at work here, I gasped (metaphorically speaking, of course, because what fourteen-year-old kid do you know, other than in a TV sitcom, who actually talks like that?). >The secret, according to the accompanying article, was that the lamp was not plugged into a normal power outlet, but rather into an outlet delivering contra-polar power. Another photograph showed a soldering iron plugged into the contra-polar power outlet; it was covered with ice! And another displayed a frozen ice tray on a hot plate, except it was now a cold plate because it was plugged into contra-polar power. I looked at those three photographs, and I remember my pulse rate elevated and I felt a momentary spell of faintness. This was simply wonderful. Needless to say that the editors "blamed" these wonderful phenomena on ''imaginary numbers''. Also needless to repeat that this issue was an [[April 1, 1955 issue|http://www.rfcafe.com/references/popular-electronics/contra-polar-energy-april-1955-popular-electronics.htm]] ... :) ''Footnote 4'' at the bottom of that article enlightened (ha!) or lifted the ''cone of darkness'' off the dense: ^^4^^ Transactions of the ~Contra-Polar Energy Commission, Vol. 45, pp. 1324-1346 (Ed. Note - A reprint of a document found in a flying saucer). In keeping with the first day of April...
<svg class="tc-image-quote tc-image-button" viewBox="0 0 128 128" width="12pt" height="12pt"></svg>
<svg class="tc-image-quote tc-image-button" width="12pt" height="12pt" viewBox="0 0 128 128">
<g fill-rule="evenodd">
<path d="M51.2188077,117.712501 L51.2188077,62.1993386 L27.4274524,62.1993386 C27.4274524,53.3075754 29.1096526,45.797753 32.4741035,39.669646 C35.8385544,33.541539 42.0867267,28.9154883 51.2188077,25.7913554 L51.2188077,2 C43.7689521,2.96127169 36.8599155,5.18417913 30.4914905,8.668789 C24.1230656,12.1533989 18.6559149,16.5391352 14.0898743,21.8261295 C9.52383382,27.1131238 5.97919764,33.2411389 3.45585945,40.2103586 C0.932521268,47.1795784 -0.208971741,54.6293222 0.0313461819,62.5598136 L0.0313461819,117.712501 L51.2188077,117.712501 Z M128,117.712501 L128,62.1993386 L104.208645,62.1993386 C104.208645,53.3075754 105.890845,45.797753 109.255296,39.669646 C112.619747,33.541539 118.867919,28.9154883 128,25.7913554 L128,2 C120.550144,2.96127169 113.641108,5.18417913 107.272683,8.668789 C100.904258,12.1533989 95.4371072,16.5391352 90.8710666,21.8261295 C86.3050261,27.1131238 82.7603899,33.2411389 80.2370517,40.2103586 C77.7137136,47.1795784 76.5722206,54.6293222 76.8125385,62.5598136 L76.8125385,117.712501 L128,117.712501 Z"></path>
</g>
</svg>
In a recent level-headed [[post on his blog|https://rpseawright.wordpress.com/2016/01/05/here-we-go-again-forecasting-follies-2016/]], Robert P. Seawright (the Chief Investment & Information Officer for Madison Avenue Securities, LLC) points out a few (unsurprising, but regularly ignored) facts about predicting the behavior of the economy, the market (and everything :). He starts by giving numerous examples of past financial predictions by pundits, mavens, experts, and generally highly-paid, highly-followed people being wrong with their forecasts (Just looking at the predictions about the S&P500 from the likes of top people at Goldman Sachs,Barclays, Credit Suisse, Deutsche Bank, Citi, Bank of America, Merrill Lynch, Morgan Stanley, and others). He also lists a few non-financial predictions by well-respected people considered experts in their fields, totally missing it in their own area of expertise. For example: - In 1995, [[analyst Clifford Stoll mocked the predictions|http://www.newsweek.com/clifford-stoll-why-web-wont-be-nirvana-185306]] that newspapers and database-driven news services will go online, and that we will buy books, etc. on the internet. - In 1996, the man widely credited with the invention of Ethernet technology, [[Bob Metcalfe predicted|http://www.scientificamerican.com/article/pogue-all-time-worst-tech-predictions/]] that the Internet will soon go spectacularly supernova and then catastrophically collapse. - in 1961 Federal Communications Commission commissioner T.A.M. Craven stated that there is no chance that communications space satellites will be used to provide better telephone, telegraph, television or radio service inside the United States. - in 1912 [[Marconi predicted|http://earlyradiohistory.us/1912mar.htm]] that the “wireless era” would make war ridiculous and impossible. (to be fair, he also predicted that "within the next two generations we shall have not only wireless telegraphy and telephony, but also wireless transmission of all power for individual and corporate use, wireless heating and light, and wireless fertilizing of fields." - and he wasn't off by much!) - In 1962, Decca records rejected the Beatles and totally missed the Beatlemania. - And you can see [[more at Scientific American|http://www.scientificamerican.com/article/pogue-all-time-worst-tech-predictions/]]. The point is not to mock the forecasters. [[Cullen Roche brings up some excellent points|http://www.pragcap.com/the-confirmation-bias-of-the-anti-forecasters/]] about interpreting forecasts in context: > When presented in a biased manner it does prove that economists are quite bad at predicting recessions. But what if I presented this data as evidence that economists are usually optimistic and the economy rarely goes into recession? > [...] Of course, you have to keep things in the right perspective. The anti-forecasters want everyone to believe that there is some way to make decisions about the future without making forecasts. This is obviously nonsense since any decision about the future involves an implicit forecast about future outcomes. Those who shun forecasting are merely trying to confirm their own biased perspectives. The reality, as I’ve shown before, is that we shouldn’t shun forecasts. We should shun low probability forecasts. > [...] Making decisions about the future necessarily involves some framework within which we explicitly or implicitly forecast future outcomes. Whether we’re crossing the street or allocating assets we have to make a forecast about how certain things might play out and what the probability of success might be. Seawright also adds that: > As Philip Tetlock wrote in his wonderful new book, [[Superforecasting: The Art and Science of Prediction|http://www.superforecasting.com/]]: “We are all forecasters. When we think about changing jobs, getting married, buying a home, making an investment, launching a product, or retiring, we decide based on how we expect the future to unfold.” So, if forecasting is critical to our survival and success, and we do it all the time, we should be interested in becoming better at it. In the book Superforecasting Tetlock makes excellent points about learning to be better forecasters. * Base predictions on data and logic, and try to eliminate personal bias. * Working in teams and seeking advice and other perspectives helps. * Keep track of records so that you know how accurate you (and others) are. * Think in terms of probabilities and recognize that everything is uncertain. * Unpack a question into its component parts, distinguishing between what is known and unknown, and scrutinizing your assumptions. * Recognize that the further out the prediction is designed to go, the less specifically accurate it can be. That is, we need: * rigorous empiricism, * probabilistic thinking, * a recognition that absolute answers are extremely rare, * regular reassessment, * accountability, and * an avoidance of too much precision. Or, more fundamentally: * We need more humility and more diversity among those contributing to decisions. * We need to be concerned more with process and improving our processes than in outcomes, important though they are (“What you think is much less important than how you think,” says Tetlock) * Superforecasters regard their views “as hypotheses to be tested, not treasures to be guarded.” Tetlock says that > most people “are too quick to make up their minds and too slow to change them.”
In Computer Science: Simplicity does not precede complexity, but follows it. and my paraphrase: In life: mindfulness does not precede full-mindness, but follows it (i.e., you have to be mindful of something :)
In an interesting [[article in Quanta Magazine|https://www.quantamagazine.org/20130222-in-computers-we-trust/]] about the role of computers in Math, the author (Natalie Wolchover, senior writer and editor at Quanta Magazine) brought up some good points: * There is a difference of opinions about whether computers/computation should play a role in inventing/discovering^^1^^ new knowledge in the field of math. ** Some claim that not using computing actually stifles the progress possible in Math. *** some liken the mathematicians who refuse to use computing in their work to marathon runners insisting on running without shoes. *** I tend to agree with them (como no?!). I think that computing is a potentially very powerful tool and extender to human abilities. Not using it may limit the areas of Math we explore, since we run the risk of avoiding areas which seem "intractable", but which may only be "calculation/computation intensive". Yes, there is beauty to the art of doing math "barefooted", and as the saying goes "necessity is the mother of invention", so doing things only "by hand" may result in ingenious solution, but there is also a price/risk for avoiding computing, entirely. **** As the article states: Deducing new truths about the mathematical universe has almost always required intuition, creativity and strokes of genius, not plugging-and-chugging. In fact, the need to avoid nasty calculations (for lack of a computer) has often driven discovery, leading mathematicians to find elegant symbolic techniques like calculus. *** But on the flip side: "Some of the problems we do today are completely uninteresting but are done because it’s something that humans can do.” *** And: “Am I doing the kind of math I’m doing because I can’t use a computer, or am I doing what I’m doing because it’s the best thing to do?” he said. “It’s a good question.” *** And in [[another article in Quanta|https://www.quantamagazine.org/20150519-will-computers-redefine-the-roots-of-math/]] Vladimir Voevodsky (a permanent faculty member at the Institute for Advanced Study (IAS) in Princeton, N.J.) said: >>> “The world of mathematics is becoming very large, the complexity of mathematics is becoming very high, and there is a danger of an accumulation of mistakes,” Voevodsky said. Proofs rely on other proofs; if one contains a flaw, all others that rely on it will share the error. **** This is something Voevodsky has learned through personal experience. In 1999 he discovered an error in a paper he had written seven years earlier. Voevodsky eventually found a way to salvage the result, but in an article last summer in the IAS newsletter, he wrote that the experience scared him. He began to worry that unless he formalized his work on the computer, he wouldn’t have complete confidence that it was correct. ** Others (who don't use computers as math tools/enhancers) claim: *** "Computers are now used extensively to discover new conjectures by finding patterns in data or equations, but they cannot conceptualize them within a larger theory, the way humans do. Computers also tend to bypass the theory-building process when proving theorems". *** “Pure mathematics is not just about knowing the answer; it’s about understanding”. “If all you have come up with is ‘the computer checked a million cases,’ then that’s a failure of understanding.” *** the biggest danger of using a computer proof: What if there’s a bug? And there are always bugs in software! Mathematicians use Computing in several ways: * One is proof-by-exhaustion: setting up a proof so that a statement is true as long as it holds for a huge but finite number of cases and then programming a computer to check all the cases. * More often, computers help discover interesting patterns in data, about which mathematicians then formulate conjectures, or guesses. Significant insights can be gained by looking for patterns in the data and then proving them. * As motivators for the hard work of proofing: Using computation to verify that a conjecture holds in every checkable case, and ultimately to become convinced of it, “gives you the psychological strength you need to actually do the work necessary to prove it”. * Increasingly, computers are helping not only to find conjectures but also to rigorously prove them. Algorithms can perform symbolic computations, manipulating variables instead of numbers to produce exact results free of rounding errors. I think that Jordan Ellenberg (a professor at the University of Wisconsin who uses computers for conjecture discovery and then builds proofs by hand) sums it the best: >[He] like many of his colleagues, sees a more significant role for humans in the future of his field: “We are very good at figuring out things that computers can’t do. If we were to imagine a future in which all the theorems we currently know about could be proven on a computer, we would just figure out other things that a computer can’t solve, and that would become ‘mathematics.’ ” If this is not called PROGRESS in a field, I don't know what is! ---- ^^1^^ - A big question is whether [[Math is invented or discovered|Is Math a human invention or a series of discoveries of truths in the real world?]].
> What an odd thing parentheses can be. The things you put in may be more important than those you leave out. : -- [[Torquing|On torquing expressions into new meanings]] Simone de Beauvoir (reflecting on diaries) I tend to use parentheses (and quotation marks :) in my writing (quite often, I might add). You can look at a (parenthetically enriched :) example in [[The Holy War: Mac vs. DOS]] (celebrating the excellent writer, Umberto Eco, who is also using parentheses very effectively (and he definitely had something to say about them^^1^^ in his tongue-in-cheek [["Style Guide"|Umberto Eco's Rules for Writing (Well)]] ). Some (many?) people frown at the use of parentheses (I'm not sure why), so I was delighted to read that an author I like Neil Gaiman, mentioned in [[one of his non-fiction pieces|http://journal.neilgaiman.com/2012/01/speech-i-once-gave-on-lewis-tolkien-and.html]], that even as a young boy/reader, he had noticed and appreciated C.S. Lewis (and other writers he loved) using parentheses: >C.S. Lewis was the first person to make me want to be a writer. He made me aware of the writer, that there was someone standing behind the words, that there was someone telling the story. I fell in love with the way he used parentheses — the auctorial asides that were both wise and chatty, and I rejoiced in using such brackets in my own essays and compositions through the rest of my childhood. In that piece, Gaiman (to my delight :) also makes nice (and [[correct|http://www.wikihow.com/Use-Parentheses]]) use of parentheses: >Father Brown^^2^^, that prince of humanity and empathy, was a gateway drug into the harder stuff, this being a one-volume collection of three novels: The Napoleon of Notting Hill (my favourite piece of predictive 1984 fiction, and one that hugely informed my own novel Neverwhere), The Man Who Was Thursday (the prototype of all Twentieth Century spy stories, as well as being a Nightmare, and a theological delight), and lastly The Flying Inn (which had some excellent poetry in it, but which struck me, as an eleven-year old, as being oddly small-minded. I suspected that Father Brown would have found it so as well.) Then there were the poems and the essays and the art. Since I am into Computer Science and programming, I have to quote here from [[James Iry's blog|http://james-iry.blogspot.com/2009/05/brief-incomplete-and-mostly-wrong.html]], a humorous take on parentheses as it relates to coding (in certain programming languages): >In 1958 John ~McCarthy and Paul Graham invent LISP. Due to high costs caused by a post-war depletion of the strategic parentheses (AKA braces) reserve LISP never became popular. Fortunately for computer science the supply of curly braces^^3^^ and angle brackets^^4^^ remains high. ---- ^^1^^ - (Always) remember that parentheses (even when they seem indispensable) interrupt the flow. ^^2^^ - a fictional Roman Catholic priest and amateur detective who featured in 53 short stories published between 1910 and 1936 written by English novelist G. K. Chesterton. ^^3^^ - Java-style ^^4^^ - ~HTML-style
Prime numbers are interesting (some would even say "fascinating" :) and useful, but since some people "don't get it", consider this as "nerd alert" :) The mathematician Richard Kenneth Guy (in a [[paper titled "The Strong Law of Small Numbers"|https://www.maa.org/sites/default/files/images/images/upload_library/22/Ford/Guy697-712.pdf]]) said: >Two of the most important elements in mathematical research are asking the right questions and recognizing patterns. On which Martin Gardner (in his [[book The Last Recreations|https://bobson.ludost.net/copycrime/mgardner/gardner15.pdf]]) commented: >Unfortunately there is no procedure for generating good questions and no way of knowing whether an observed pattern will lead to a significant new theorem or whether the pattern is just a lucky coincidence. which strikes me as very similar to the situation with prime numbers: there is no procedure/algorithm for finding/producing them, and they seem to defy all attempts to find patters for their occurrence (but, for example, the mathematician Stanislaw Ulam came up with [[some creative discoveries|https://en.wikipedia.org/wiki/Ulam_spiral]]). Gardner also wrote (in //Martin Gardner's Mathematical Games//): >No branch of number theory is more saturated with mystery and elegance than the study of prime numbers: those exasperating, unruly integers that refuse to be divided evenly by any integers except themselves and 1. which sounds very poetic (to be expressed by a mathematician :), but as a matter of fact, prime numbers appear not only in mathematics, but also in "that other human endeavor that delves into mysteries in search of patterns and elegance -- poetry"^^1^^. So here is an example by the British poet and writer Helen Spalding ([[quoted both by Martin Gardner (in "The Last Recreations")|https://bobson.ludost.net/copycrime/mgardner/gardner15.pdf]] and in [[an article by Sarah Glaz|http://www.math.uconn.edu/~glaz/My_Articles/ThePoetryOfPrimeNumbers.Bridges11.pdf]]): ''Let Us Now Praise Prime Numbers'' """ Let us now praise prime numbers With our fathers who begat us: The power, the peculiar glory of prime numbers Is that nothing begat them, No ancestors, no factors, Adams among the multiplied generations. None can foretell their coming. Among the ordinal numbers They do not reserve their seats, arrive unexpected. Along the lines of cardinals They rise like surprising pontiffs, Each absolute, inscrutable, self-elected. In the beginning where chaos Ends and zero resolves, They crowd the foreground prodigal as forest, But middle distance thins them, Far distance to infinity Yields them rare as unreturning comets. O prime improbable numbers, Long may formula-hunters Steam in abstraction, waste to skeleton patience: Stay non-conformist, nuisance, Phenomena irreducible To system, sequence, pattern or explanation. """ ---- ^^1^^ from [[an article by Sarah Glaz|http://www.math.uconn.edu/~glaz/My_Articles/ThePoetryOfPrimeNumbers.Bridges11.pdf]].
Neal Stephenson's In the Beginning was the Command Line:
The cosmic operating system uses a command-line interface. It runs on something like a teletype, with lots of noise and heat; punched-out bits flutter down into its hopper like drifting stars. The demiurge^^1^^ sits at his teletype, pounding out one command line after another, specifying the values of fundamental constants of physics:
universe -G 6.672e-11 -e 1.602e-19 -h 6.626e-34 -protonmass 1.673e-27....
and when he's finished typing out the command line, his right pinky hesitates above the ENTER key for an aeon or two, wondering what's going to happen; then down it comes -- and the WHACK you hear is another Big Bang.
(compare to [[siseneG - by Arthur C. Clarke]]).
----
"""
^^1^^ demiurge n. - a being responsible for the creation of the universe.
(in Platonic philosophy) the Maker or Creator of the world.
(in Gnosticism and other theological systems) a heavenly being, subordinate to the Supreme Being, that is considered to be the controller of the material world and antagonistic to all that is purely spiritual.
"""
In the beginning was the Tao. The Tao gave birth to Space and Time. Therefore Space and Time are Yin and Yang of programming. Programmers that do not comprehend the Tao are always running out of time and space for their programs. Programmers that comprehend the Tao always have enough time and space to accomplish their goals. How could it be otherwise? - from [[The Tao of Programming|http://canonical.org/~kragen/tao-of-programming.html]]
In the design of programming languages, one can let oneself be guided by considering "what the machine can do". Considering, however, that the programming language is the bridge between the user and the machine - that it can, in fact, be regarded as his tool - it seems just as important to take into consideration "what man can think".
In three words I can sum up everything I've learned about life: It goes on.
In an excellent book titled [["When Einstein Walked with Gödel -- Excursions to the Edge of Thought"|https://www.nytimes.com/2018/05/15/books/review/review-when-einstein-walked-with-godel-jim-holt.html]]^^1^^, Jim Holt writes about "The Dangerous Idea of the Infinitesimal". >From the time it was conceived, the idea of the infinitely small has been regarded with deep misgiving, even more so than that of the infinitely great. How can something be smaller than any given finite thing and not be simply nothing at all? Aristotle tried to ban the notion of the infinitesimal on the grounds that it was an absurdity. David Hume declared it to be more shocking to common sense than any priestly dogma. Bertrand Russell scouted it as “unnecessary, erroneous, and self contradictory". > >Yet for all the bashing it has endured, the infinitesimal has proved itself the most powerful device ever deployed in the discovery of physical truth, the key to the scientific revolution that ushered in the Enlightenment. And, in one of the more bizarre twists in the history of ideas, the infinitesimal -- after being stuffed into the oubliette seemingly for good at the end of the nineteenth century -- was decisively rehabilitated in the 1960s [see below]. > >It now stands as the epitome of a philosophical conundrum fully resolved. Only one question about it remains open: >Is it real? And he adds: >Curiously, adding infinitesimals to the universe as Robinson contrived to do, in no way alters the properties of ordinary finite numbers. Anything that can be proved about them using infinitesimal reasoning can, as a matter of pure logic, also be proved by ordinary methods. Yet this scarcely means that Robinson's sterile. By restoring the intuitive methods that Newton had pioneered, Robinson's "nonstandard analysis” has yielded proofs that are shorter, more insightful, and less ad hoc than their standard counterparts. Indeed, Robinson himself used it early on to solve a major open problem in the theory of linear spaces that had frustrated other mathematicians. Nonstandard analysis has since found many adherents in the international mathematical community, especially in France, and had been fruitfully applied to probability theory, physics, and economics where it is well suited to model, say, the infinitesimal impact that a single trader has on prices. > >Beyond his achievement as a mathematical logician, Robinson must be credited with bringing about one of the great reversals in the history of ideas. More than two millennia after the idea of the infinitely small had its dubious conception, and nearly a century after it had been got rid of seemingly for good, he managed to remove all taint of contradiction from it. Yet he did so in a way that left the ontological status of the infinitesimal completely open. There are those, of course, who believe that any mathematical object that does not involve inconsistency has a reality which transcends the world of our senses. Robinson himself subscribed to such a Platonistic philosophy early in his career, but he later abandoned it in favor of Leibniz's view that infinitesimals were merely "well-founded fictions." > >Whatever reality the infinitesimal might have, it has no less reality than the ordinary numbers -- positive, negative, rational and irrational, real and complex, and so on -- do. When we talk about numbers, modern logic tells us, our language simply cannot distinguish between a nonstandard universe brimming with infinitesimals and a standard one that is devoid of them. So this is another example of the age-old question of [[whether math is an invention or a discovery|Is Math a human invention or a series of discoveries of truths in the real world?]]. It adds to the evolving/expanding "zoo" of mathematical entities (like the irrational numbers, transcendentals, imaginary numbers, and so on) Richard Hamming writes so well about in [[On why Math works for us]]. Holt also quotes from the book The Incredible Shrinking Man (also a 1957 science fiction film) written by Richard Matheson, making another wonderful (wondrous?) connection between life, philosophy, and mathematics; showing that small size does not mean insignificance (nor meaninglessness) (see also what [[Janna Levin|http://jannalevin.com/bio-and-contact/]] [[had to say|On Anthropic Bias, or Was the Universe Made for Us?]] in an [[interview with Krista Tippett|https://www.brainpickings.org/2015/01/09/krista-tippett-einsteins-god-janna-levin/]]): >So close — the infinitesimal and the infinite. But suddenly, I knew they were really the two ends of the same concept. The unbelievably small and the unbelievably vast eventually meet — like the closing of a gigantic circle. I looked up, as if somehow I would grasp the heavens. The universe, worlds beyond number, God's silver tapestry spread across the night. And in that moment, I knew the answer to the riddle of the infinite. I had thought in terms of man's own limited dimension. I had presumed upon nature. That existence begins and ends in man's conception, not nature's. And I felt my body dwindling, melting, becoming nothing. My fears melted away. And in their place came acceptance. All this vast majesty of creation, it had to mean something. And then I meant something, too. Yes, smaller than the smallest, I meant something, too. To God [and in math], there is no zero. I still exist! ---- ^^1^^ - searchable spelling: Gödel, Godel, Goedel
From Maria Popova's Brainpickings [[article on "Wisdom in the Age of Information"|https://www.brainpickings.org/2014/09/09/wisdom-in-the-age-of-information/]]: >We live in a world awash with information^^1^^, but we seem to face a growing scarcity of wisdom. And what’s worse, we confuse the two. We believe that having access to more information produces more knowledge, which results in more wisdom. But, if anything, the opposite is true — more and more information without the proper context and interpretation only muddles our understanding of the world rather than enriching it^^2^^. Which is similar to what Michael P. Lynch writes in his book //The Internet of Us - Knowing More and Understanding Less in the Age of Big Data// ([[a book reviewed by Jill Lepore|After The Fact - In the history of truth, a new chapter begins]]) >When we Google-know, we no longer take responsibility for our own beliefs, and we lack the capacity to see how bits of facts fit into a larger whole. Essentially, we forfeit our reason and, in a republic, our citizenship. You can see how this works every time you try to get to the bottom of a story by reading the news on your smartphone. And Popova continues: >Ours is a culture where it’s enormously embarrassing not to have an opinion on something, and in order to seem informed, we form our so-called opinions hastily, based on fragmentary bits of information and superficial impressions rather than true understanding. >[...] At its base is a piece of information, which simply tells us some basic fact about the world. Above that is knowledge — the understanding of how different bits of information fit together to reveal some truth about the world. Knowledge hinges on an act of correlation and interpretation. At the top is wisdom, which has a moral component — it is the application of information worth remembering and knowledge that matters to understanding not only how the world works, but also how it should work. And that requires a moral framework of what should and shouldn’t matter, as well as an ideal of the world at its highest potentiality. (See also [[From Noise to Wisdom]]). On the lighter side, an [[insightful joke on the nature of knowledge|Learning and Examinations]]. ---- ^^1^^ or as Edna St. Vincent Millay, in her sonnet “Upon This Age That Never Speaks Its Mind” wrote (in 1939): >Upon this gifted age, in its dark hour, >Rains from the sky a meteoric shower >Of facts . . . they lie unquestioned, uncombined. >Wisdom enough to leech us of our ill >Is daily spun; but there exists no loom >To weave it into fabric. ^^2^^ echoing Alan Kay's condemnation (in a [[video (43 min.)|https://www.youtube.com/watch?v=gTAghAJcO1o]]) of the popular trend of Big Data, when he is saying it should not be about Big Data, but about [[Big Meaning|http://planspace.org/20141125-alan_kay_on_big_data/]].
Albert Einstein once said: > The difference between what the most and the least learned people know is inexpressibly trivial in relation to that which is unknown. It seems that the mathematician and computer scientist [[Gregory Chaitin|https://en.wikipedia.org/wiki/Gregory_Chaitin]] agrees. In an [[interesting and touching interview of Gregory Chaitin|https://www.whyarewehere.tv/people/gregory-chaitin/]] he talks about WHAT WE DON’T KNOW: >Ard: Yesterday we talked to Marcelo Gleiser and he talked about the idea of knowledge like an island. So as you grow… an island in a sea of ignorance. So as knowledge grows, so does the size of the border that you have of the ignorance that you see. So as you get more and more knowledge, you also see more and more ignorance. > >GC: That’s a very nice image. Also people don’t like talking about what they don’t know. They like talking about what they know. I’m the other way around. I prefer thinking about what I don’t know. > >Certainty is bad because it’s uncreative. It means you know already – you don’t need to think any more about it. Well it’s also totally uncreative in mathematics. The idea of Hilbert was to ensure certainty. He thought it was possible: he thought the possibility of doing this is what it meant to say that mathematics was black or white, that mathematical truth is more solid than any empirical truth. And it’s wonderful that mathematics refuted this. > >You know, [ext[Gödel’s Incompleteness Theorem|resources/Boolos-godel-in-single-syllables.pdf]] is suppressed (see also [[The world's shortest explanation of Gödel's theorem]]). The mathematics community doesn’t want to take it into account, because they view it as a tremendously pessimistic, horrible fact that you can’t have a ‘theory of everything’ for mathematics, and that mathematics doesn’t give absolute truth. I think this is absolutely wonderful. The viewpoint is wrong. What Gödel’s Theorem is about… it’s not a negative theorem, it’s a positive theorem. It’s about creativity. It’s the first step in the direction of a mathematical theory of creativity – of saying that math is not a closed system, it’s an open system, just like biology. And this is totally liberating and we should all celebrate…. celebrate this fact rather than bemoaning it, beating our breast, ‘Oh my God. What happened to absolute truth in mathematics?’ Well, what happened was that absolute truth was a closed system. It was a prison: the notion of a formal theory that would give you absolute certainty. > >Ard: A theory of everything. > >GC: A theory of everything. Yes, a formalisation of all of mathematics in one finite set of axioms. This would have been horrifying. > >Let’s say that they have this computer program which can decide if mathematical assertions are true or false. > >Well, what good is it to know whether something is true or false? You want to understand what’s happening, right? > >David: The why rather than the… > >GC: The why, exactly. You want to be convinced emotionally that something is true. That’s why new questions are important, because what counts is not the mathematics we know – the science we know is uninteresting – it’s what we don’t know that’s interesting. > >Unfortunately universities spend all their time filling your head with what’s known, but that’s totally trivial. What’s interesting is what we don’t know. That’s what all the courses should be about, so that maybe the students can come up with new ideas before they’ve been brainwashed with the current paradigms. That would be the university I would create, you know, which only would talk about what we don’t know because what we know is really very uninteresting.
Insofar as the laws of mathematics refer to reality, they are not certain. And insofar as they are certain, they do not refer to reality.
From [[an article|https://www.shanesnow.com/articles/intellectual-humility]] (and a [[self-assessment|https://www.shanesnow.com/articles/intellectual-humility#take-the-intellectual-humility-assessment]] questionnaire) by Shane Snow on Intellectual Humility. Snow writes that Intellectual Humility (IH) >is a virtue and one of the biggest keys to making progress in teamwork, creative solo work, and society. >If everyone in the world developed more of this virtue, a lot would change. Innovation would skyrocket. War and violence would plummet. Facebook arguments would actually be productive. >To be truly intellectually humble, we need to develop respect for people and ideas that are different than our own, overcome our overconfidence, and take control of our ego. >This sets us up to be able to revise our viewpoints when it's important to do so. All together, this is what it means to be "Intellectually Humble:” * ''Openness to New Experiences & Information'' ** Being open to new experiences and information is not part of Intellectual Humility, but it helps us learn about things we can then use Intellectual Humility with. (but as Carl Sagan said: Keeping an open mind is a virtue, but… not so open that your brains fall out.) * ''Respect for Other Viewpoints'' ** Unearth the moral foundations of the other person's viewpoint. ** Gain empathy by learning the other person's story. ** Reduce fear of the other person by playing & laughing together. ** Increase your general respect for others by living abroad, reading and watching fiction, and learning multiple languages. * ''Lack of Intellectual Overconfidence'' ** Understand the "math" of how diverse perspectives can make a group smarter than its smartest individual. ** When sharing strong viewpoints, acknowledge, "I could be wrong." ** Leave room for discussion by avoiding verbal absolutes like "always" and "clearly" when sharing viewpoints. ** Acknowledge when you don't know something, but add that you just don't know it "Yet." * ''Separation of Ego & Intellect'' ** Get to know your ego through the [[Enneagram framework|https://www.enneagraminstitute.com/how-the-enneagram-system-works/]]. ** Identify when discussions or topics veer into personal territory. ** Don't invoke identity when expressing viewpoints. ** Practice mindfulness meditation. * ''Willingness to Revise Viewpoints'' ** Changing our minds requires us to consider other viewpoints, acknowledge we could be wrong, and not take ideas personally. At that point, revising our viewpoint is almost a piece of cake. ** one very straightforward thing we can do to build up our ability to revise our viewpoints: Travel. Either physically, or through fiction.
!!!!Why The Interactive Solutions Guide (ISG) I designed and implemented as part of my role as a "Performance Support Specialist" at Cisco Systems, was built to enable Cisco partners (sales people and Systems Engineers) to "correctly configure and sell Cisco networking solutions, which meet customer needs and requirements". !!!!What The ISG was designed to replace most of the traditional training that was originally proposed for the "on-boarding" of Cisco partners. It was a software tool built around an inference engine, which helped partners assess the customer needs, collect information about the customer networking environment, and configure a solution based on Cisco equipment to satisfy the customer requirements, and present/justify the proposed solution. !!!!Human Performance Support The system embedded a few Human Performance Support principles: * combining learning with doing ** the system supported learning while doing, by offering information about networking technologies, Cisco equipment, device configurations, and so on, all embedded within the performance activities of assessing the customer needs and environment, selecting an appropriate solution, and preparing the presentation of that solution. * just-in-time, on-demand training ** the learning resources and activities were available within the work context, enabling the performer to go back and forth between learning and doing without switching context * Deep performance support ** the system provided information, examples, skills training activities, decision support (via the inference engine), and task automation (through automating configuration tasks, presentation and justification).
The Drake Equation (as opposed to [[The Flake Equation]] :) is a good example of combining knowledge from multiple disciplines. A reminder: The equation is @@font-size:14pt; N = R* • f~~p~~ • n~~e~~ • f~~l~~ • f~~i~~ • f~~c~~ • L @@ where: N = The number of civilizations in the Milky Way galaxy whose electromagnetic emissions are detectable. R* =The rate of formation of stars suitable for the development of intelligent life. f~~p~~ = The fraction of those stars with planetary systems. n~~e~~ = The number of planets, per solar system, with an environment suitable for life. f~~l~~ = The fraction of suitable planets on which life actually appears. f~~i~~ = The fraction of life bearing planets on which intelligent life emerges. f~~c~~ = The fraction of civilizations that develop a technology that releases detectable signs of their existence into space. L = The length of time such civilizations release detectable signals into space. Smart and thoughtful people grappled with the equation and its implications, from [[Enrico Fermi|https://www.nobelprize.org/nobel_prizes/physics/laureates/1938/fermi-bio.html]] (posing the famous [[Fermi Paradox|https://www.seti.org/seti-institute/project/details/fermi-paradox]]), through [[Ray Kurzweil|pg. 53 - RAY KURZWEIL: WHERE ARE THEY?]], [[Frank Wilczek|Frank Wilczek on Intelligent Life in the universe]], Carl Sagan, and many more. In an article titled [[Greetings, E.T. (Please Don’t Murder Us.)|https://www.nytimes.com/2017/06/28/magazine/greetings-et-please-dont-murder-us.html]] Steven Johnson makes some interesting observations about (among other things :) the interdisciplinary nature of the Drake Equation, combining science, philosophy, morality, religion, politics. >What makes the Drake Equation so mesmerizing is in part the way it forces the mind to yoke together so many different intellectual disciplines in a single framework. As you move from left to right in the equation, you shift from astrophysics, to the biochemistry of life, to evolutionary theory, to cognitive science, all the way to theories of technological development. Your guess about each value in the Drake Equation winds up revealing a whole worldview: Perhaps you think life is rare, but when it does emerge, intelligent life usually follows; or perhaps you think microbial life is ubiquitous throughout the cosmos, but more complex organisms almost never form. The equation is notoriously vulnerable to very different outcomes, depending on the numbers you assign to each variable. > >The most provocative value is the last one: L, the average life span of a signal-transmitting civilization. You don’t have to be a Pollyanna to defend a relatively high L value. All you need is to believe that it is possible for civilizations to become fundamentally self-sustaining and survive for millions of years. Even if one in a thousand intelligent life-forms in space generates a million-year civilization, the value of L increases meaningfully. But if your L-value is low, that implies a further question: What is keeping it low? Do technological civilizations keep flickering on and off in the Milky Way, like so many fireflies in space? Do they run out of resources? Do they blow themselves up? And Johnson points out that a new level of thinking and behavior as a species may be required at this stage of our civilization, again, requiring a highly-interdisciplinary knowledge and skills: >Wrestling with the [[METI|http://meti.org/mission]] question suggests, to me at least, that the one invention human society needs is more conceptual than technological: We need to define a special class of decisions that potentially create extinction-level risk. New technologies (like superintelligent computers) or interventions (like METI) that pose even the slightest risk of causing human extinction would require some novel form of global oversight. And part of that process would entail establishing, as [[[Dr. Kathryn] Denning|http://www.yorku.ca/kdenning/seti.htm]] suggests, some measure of risk tolerance on a planetary level. If we don’t, then by default the gamblers will always set the agenda, and the rest of us will have to live with the consequences of their wagers. >[...] There is not a lot of historical precedent for humans voluntarily swearing off a new technological capability — or choosing not to make contact with another society — because of some threat that might not arrive for generations. But maybe it’s time that humans learned how to make that kind of choice. This turns out to be one of the surprising gifts of the METI debate, whichever side you happen to take. Thinking hard about what kinds of civilization we might be able to talk to ends up making us think even harder about what kind of civilization we want to be ourselves.
I recently came across an [[interesting chapter|resources/WHEN THINGS START TO THINK - Chapter 13 - Information and Education.docx]] from Neil Gershenfeld's book "When Things Start to Think" (see [[chapters online|http://www.kurzweilai.net/neil-gershenfeld]]), talking about (among other things ;-) why he started teaching two (1 semester long) courses at MIT, one covering the physical world outside of computers (The Physics of Information Technology), and the other the logical world inside computers (The Nature of Mathematical Modeling). Gershenfeld tells a story explaining what triggered his decision to teach these courses. In a nutshell: >One week an MIT undergrad, and independently an MIT professor, asked me the same question: how does the bandwidth of a telephone line relate to the bit rate of a modem? >... >I was surprised to find that someone could be at MIT as long as both the student and professor had been, studying communications in many forms, and never have heard of a result as important as this. Not only that, both were unprepared to understand where it came from and what conclusions might be drawn from it. >Entropy shows up in two places in their question, ... one having to do with materials and thermal noise calculations, and the other having to do with information density and bit-rate calculations. >Although these two calculations are closely related, physicists learn how to do the former in one part of campus, and engineers the latter in another. In other words, topics are taught/covered in "silos", and very powerful and useful connections are being missed or ignored. >Very few students manage to be sufficiently bilingual to be able to do both. Those who are either take so many classes beyond the usual load that they manage to squeeze in a few different simultaneous degrees, or take so few classes that they have enough time to put these pieces together on their own. Either path requires unusual initiative to answer such a reasonable question. And that's why Gershenfeld decided to teach these 2 unique courses: >Faced with students who knew a lot about a little, I decided that I had to teach everything. >... >My students loved them; some of my peers at MIT hated them. This was because each week I would cover material that usually takes a full semester. >... >I did this by teaching just those things that are remembered and used long after a class has ended, rather than everything that gets thrown in. And this resonated with me on several levels. * On the personal level, I know that I like to learn this way, that is, start with something I really, really want to do or know, and follow the trail (or "pull the string in the spool"), with a strong sense of purpose and direction, taking "side excursions" and doing "deep-dives" when needed (or wanted), to cover additional topics and acquire additional skills. ** This is for example, how I learned most of the new programming languages (and I know a few ;-) I have acquired //after// graduating from university (where they teach programming languages the "linear way" chapter after chapter). I didn't read the books or manuals from cover to cover, but rather started with the introduction covering things like the "philosophy", motivations, guiding principles, etc. of the language, followed by things like unique language features, data structures, models, abstractions, etc., and then diving into the techniques and hands on exercises, all "in service" of the original goal or need I had in mind. ** In other words, I carved ''a unique path through the knowledge and skills space''. ** This learning path works best when guided by a strong and unifying goal like a project. In other words, ''project-based learning'' by definition will create a path through one or more knowledge domains. And this type of learning is also [[advocated by Symour Papert|An Exploration in the Space of Mathematics Educations]]. *** It's not surprising that Neil Gershenfeld from the [[Center for Bits and Atoms|http://cba.mit.edu/]] (spawned from the MIT Media Lab) is advocating Interdisciplinary and Project-based Learning, too. Papert was a founding faculty member of the Lab... * On the pedagogical level, this idea of a ''knowledge domain'' (consisting of topics and relationships, forming a "knowledge map") that can be viewed and traversed according to individual needs, skills, and interest is similar to a [[project/proposal|resources/LDT Just-in-time Learning for Performance - Solution.jpeg]] I worked on at Stanford University, as part of the Learning, Design, and Technology (LDT) Masters program. ** These kinds of individual views and paths through a knowledge domain or map reflect the learner's existing knowledge and skill levels, their preferred learning styles, desired/required mastery level, etc. ** A solution I proposed as a [[just-in-time performance and learning system|resources/LDT JIT Performance Support.pdf]] describes how to design and apply knowledge domains, knowledge/topic maps, knowledge and skills assessments, to create effective learning and performing environments (after all, excellent personal performance is an important goal and driver for learning). ** A [[very rudimentary 3D pivoting view|resources/LDTtutoringSystemMonitor1.png]] of some relevant learning parameters in a simple knowledge domain (such as mastery level, topic coverage, and learning time) was also incorporated into another prototype I did as part of an [[automated tutoring system|An online intelligent tutoring system with knowledge maps and second-order feedback]]. I think that there is a lot of merit in combining the motivation that Gershenfeld had for designing his courses with domain knowledge maps like the ones developed at the Khan Academy. There is definitely a need (and an "audience") for the very structured and exhaustive path through such a domain, following and fulfilling the prerequisites and established paths and relationships. But, there is also a strong need (and audience - maybe bright and focused university students, and/or life-long learners) that need and can benefit from a customized/personal path through a domain, in light of their strong focus, desires, or need. And that's where providing these capabilities (views, personalization, navigation) are critical and very useful. Or in Gershenfeld's words: >Although this brisk pace does a disservice to any one area, unless I teach this way most people won t see most things. It is only by violating the norms of what must be taught in each discipline that I can convey the value of the disciplines. >It's not a discipline, a distinct body of knowledge that has stood the test of time and that brings order to a broad area of our experience. Progress on the former relies on the latter. >Universities go on filling students with an inventory of raw knowledge to be called on later; this is sensible if the world is changing slowly, but it is not. An alternative is [[just-in-time education|resources/LDT JIT Performance Support.pdf]], drawing on educational resources as needed in support of larger projects. >The faster the world changes, the more precious traditional disciplines become as reliable guides into unfamiliar terrain, but the less relevant they are as axes to organize inquiry. And also: >The inconvenient technology that we live with reflects the inconvenient institutional divisions that we live with. To get rid of the former, we need to eliminate the latter.
As pattern- and/or meaning-seeking creatures, we tend to assign significance to all sorts of sets, combinations, series, and events. I came across (incidentally? I don't think so! :) an interesting tool called [[RIES - Find Algebraic Equations, Given Their Solution|http://mrob.com/pub/ries/]], which is an Inverse Equation Solver. The author of the web-based tool has a long page of "[[interesting numbers|http://mrob.com/pub/math/numbers.html]]" and their relationships. Here is what [[RIES produces|http://mrob.com/pub/ries/ries.php?target=3.141592653589&rst=c]] for 3.141592653589 (pi): [img[RIES - pi|resources/ries_pi_1.png][resources/ries_pi.png]] The author of RIES, [[Robert Munafo|http://mrob.com/pub/personal.html]], also suggests a few tips and tricks for playing with numerical relationships and assigning meaning to them (after the fact, and by design, of course :) * [[Pre-destined and linked fortunes|http://mrob.com/pub/ries/index-3.html#pre_destiny]] (linking 2 phone numbers) * [[Four Fours|http://mrob.com/pub/ries/index-3.html#four]] (producing any number with a restricted set) * [[Area 51|http://mrob.com/pub/ries/index-3.html#area_51]] (the [[infamous UFO storage/repository|https://en.wikipedia.org/wiki/Area_51]] that [[does not exist|http://www.urbandictionary.com/define.php?term=Area%2051]] :) And here is what [[xkcd had to say|http://xkcd.com/1047/]] about this: [img[RIES - numbers|resources/ries_xkcd_1047_s.png][resources/ries_xkcd_1047.png]]
Jason Zweig wrote an insigtful article about what he learned from Kahneman about investing ([[Do You Sabotage Yourself?|https://jasonzweig.com/from-the-archives-daniel-kahneman/]]). Here are some useful highlights for investment/investors:
* Kahneman knew, chance alone dictates that an unusually good or bad event is typically followed by a much more ordinary one–what statisticians call “regression to the mean.”
* We base long-term decisions on short-term information. The “law of large numbers” holds that only a vast sample of data (a nationwide poll, say) can give an accurate picture of the population it’s drawn from. But Kahneman and Tversky found that the typical person acts on what they christened the “law of small numbers”–basing broad predictions on narrow samples of data. For instance, we buy a fund that’s beaten the market three years in a row, convinced it’s “on a hot streak”–even though a mountain of research shows that three-quarters of all funds underperform in the long run.
* If something is easy to recall, we think it happens more often than it does. Kahneman and Tversky had people listen to a list of male and female names, both famous and obscure, and then recall whether it contained more men or women. When more of the famous names were female, 81% of people concluded that women made up more than half the list–when, in fact, there were more men on the list.
** Likewise, it’s easy to recall initial public offerings that have been famously lucrative, like Cisco and Microsoft. Yet IPOs that fizzle–like, say, 3DO Co. or Quarterdeck Software–vastly outnumber those that sizzle. Historically, IPOs have actually underperformed the rest of the stock market by three to five percentage points a year, but many gung-ho investors fail to recognize that the majority of new stocks are stinkers.
* When estimating future values, we “anchor” our projections on any number that happens to be handy. In one experiment, Kahneman and Tversky asked people to estimate various statistics, such as the percentage of African countries in the United Nations. Before each person guessed, the researchers spun a “wheel of fortune” to generate a number between 0 and 100. When the wheel landed on a low number, people tended to guess that African nations made up a small percentage of UN members; when it landed on a high number, they guessed that Africa accounted for much more of the UN’s membership.
** Experiments like this prove that the mere suggestion of an outside number is enough to distort people’s views. That’s just what happens when an analyst publicizes a price target for a stock. Such targets often are utter garbage–but investors still “anchor” on them.
!!! Some Kahneman "Commandments":
Few of us are as honest about our shortcomings as Kahneman is. Yet we can all benefit from applying his insights to our portfolios. Here are the lessons I’ve learned from him.
''Distrust data''. Rather than leaping to conclusions based on scant data, look at as many numbers as possible. Don’t rely just on recent performance; look at several time periods. “It doesn’t take many observations to think you’ve spotted a trend,” warns Kahneman, “and it’s probably not a trend at all.” Merrill Lynch, for instance, recently told investors to slash their exposure to overseas stocks since foreign returns have lately resembled those of U.S stocks. But what if that proves to be an aberration?
''Chill out''. The hotter an investment’s recent returns are, the more skeptical you should be about its future. Remember to ask what eventually became of other similarly faddish investments. Until lately, years of easy profits had made investors much too confident. As Kahneman wryly notes: “In a rising market, enough of your bad ideas will pay off so that you’ll never learn that you should have fewer ideas.”
''Anchors aweigh''. When pundits like Goldman Sachs’ Abby Joseph Cohen predict where the Dow is heading, or when analysts like Morgan Stanley’s Mary Meeker forecast Amazon.com’s stock price, the market often moves magnetically in their direction. But don’t anchor your expectations to the tea leaves of the so-called experts. At best, they’re making educated guesses; at worst, they’re manipulating you to make money for their own companies.
''Use mad money''. If you can’t resist the temptation to trade stocks, put the bulk of your portfolio in a broad stock-index fund; then take a little (10% tops) to “play the market” yourself. This way, you keep your hunches on the fringe, where they belong. “It’s like going to the casino with only $200,” says Kahneman. “It helps protect you from regret.”
Step back. In scary times like these, force yourself to look at your whole portfolio. Last year, my stake in AOL Time Warner (MONEY’s parent) plunged 57% in the fourth quarter. But Kahneman has taught me to use what he calls “global framing,” or looking at the sum total of everything I own. It turns out my entire portfolio was down only 8% that quarter and was flat for the year. So I didn’t sell, because I didn’t panic–and my 57% loser has since bounced back.
''Stop counting''. “If owning stocks is a long-term project for you,” says Kahneman, “following their changes constantly is a very, very bad idea. It’s the worst possible thing you can do, because people are so sensitive to short-term losses. If you count your money every day, you’ll be miserable.” So I check the value of my investments a grand total of four times a year; while others agonize over what their stocks did from 1:24 p.m. to 1:37 p.m. today, I’m more concerned about where mine will be between the years 2024 and 2037.
''Fly on autopilot''. Many of the people who loved the Nasdaq when it was at 5000 a year ago won’t touch it now that it’s at less than half that level. Such irrational mood swings lead people to trade too much as they veer erratically between glee and dismay. “All of us,” says Kahneman, “would be better investors if we just made fewer decisions.”
Luckily, there’s a solution called dollar-cost averaging. Every month, an automatic electronic transfer sweeps money out of my bank account and into index funds. I never try to predict where the market is going; I just mechanically shovel more cash into my funds each month, regardless of whether the market has been going up, down or sideways. I call this my “permanent autopilot portfolio.” It gets me out of trying to guess what will happen next–a game that Kahneman has taught me I can’t win.
''Look within''. Most financial advice, especially on TV and the Internet, suggests that investing is an endless race to beat the market. Every day brings a breathless stream of bulletins about who’s ahead or behind. If anyone else wins, it seems, you lose. But Kahneman’s insights teach us something very different and vastly more profound: Investing isn’t about beating others at their game. It’s about controlling yourself at your own game. I’m not a penny poorer if someone in Dubuque beats the S&P 500 and I don’t. But I can ruin my family’s financial future if I lose my self-control and let my greed or fear trick me into buying high or selling low.
For each of us, risk doesn’t reside only in the market. It lurks inside ourselves–in the way we misinterpret information, fool ourselves into thinking we know more than we do or overreact to the market’s swings. By teaching me the paradox that the most powerful thing I can learn is how little I can ever possibly know, Danny Kahneman has set me free.
Addressing [[The Unreasonable Effectiveness of Mathematics]] and Wigner's observation^^1^^, the physicist Mario Livio (who has written a lot about it), writes in [[an article on PBS/KQED|http://www.pbs.org/wgbh/nova/blogs/physics/2015/04/great-math-mystery/]]: >At the core of this math mystery lies another argument that mathematicians, philosophers, and, most recently, cognitive scientists have had for a long time: Is math an invention of the human brain? Or does math exist in some abstract world, with humans merely discovering its truths? The debate about this question continues to rage today. >[...] >Personally, I believe that by asking simply whether mathematics is discovered or invented, we forget the possibility that mathematics is an intricate combination of inventions and discoveries. Indeed, I posit that humans invent the mathematical concepts—numbers, shapes, sets, lines, and so on—by abstracting them from the world around them. They then go on to discover the complex connections among the concepts that they had invented; these are the so-called theorems of mathematics. This echos [[David Darling's view|The relationship between the world out there and what's inside our mind]] that we combine perception and classification of "things out there" with mental processes in the mind as our natural/inherent mode of living and surviving. >I must admit that I do not know the full, compelling answer to the question of what is it that gives mathematics its stupendous powers. That remains a mystery. In [[another article|http://www.sfu.ca/~rpyke/cafe/livio.pdf]] Livio addresses a related question: what gives mathematics its explanatory and predictive powers? > There is no doubt that the selection of topics we address mathematically has played an important role in math's perceived effectiveness. But mathematics would not work at all were there no universal features to be discovered. You may now ask: Why are there universal laws of nature at all? Or equivalently: Why is our universe governed by certain symmetries and by locality? I truly do not know the answers, except to note that perhaps in a universe without these properties, complexity and life would have never emerged, and we would not be here to ask the question. (see Edward Nelson's perspective [[On the question of mathematics syntax and semantics]]) In an [[interesting and touching interview, Gregory Chaitin|https://www.whyarewehere.tv/people/gregory-chaitin/]] talks about "The Joy of Mathematical Discovery": >You know, there is mathematics that, as Ulam puts it, fills in much-needed gaps. There are pieces of mathematics and when you find them, they seem sort of inevitable afterwards – they weren’t in advance – and when you find a thing like that, then it seems more real, then it seems that you’re discovering it. But let’s face it, from a practical point of view we’re inventing it as we go. > >But it’s true that on good days, when you’ve found something that you really love, you say, ‘Oh, my God.’ You have a feeling of inevitability that you’re discovering something, that there’s this beautiful thing out there that it really doesn’t feel like any mortal could have invented it. It seems to be something from the Platonic universe of beautiful ideas or from God’s mind. Who knows? > >So that’s if you’re very lucky. The whole thing seems so beautiful and so natural and so fundamental that you say, ‘How come I didn’t see it before? How come nobody saw it before?’ >That’s a very wonderful feeling, I have to say. But it took ten years to get there because the mathematics was clumsy and awkward, as new mathematics always is. Then people polish it for 300 years... But discovering mathematics is messy, like making love; it’s messy. > >[...] But there are wonderful moments when, yes, you have this feeling, and then moments like that you say, ‘Well, it wasn’t me. I didn’t discover this. This idea exists out there independently of me and maybe it wanted to use me to express itself.’ > >But maybe it’s a way of fooling ourselves. But this is the kind of thing that helps you to do good mathematics. You have to be inspired. It’s profoundly emotional. I mean, the best mathematics is an art. It’s totally creative. You have to throw your whole personality at it. And it may be that you discover something because you’re crazy. You were the right crazy person to come up with this crazy idea, but other crazy people don’t find anything because their craziness isn’t in sync with the next discovery that had to be made. > >David: I was fascinated when you said, ‘Sometimes you feel like the idea just needed you.’ > >GC: It needed people to express it. It wanted to incarnate, so to speak. > >David: Well, I sometimes think that ideas are like a seed. > >GC: Absolutely. > >David: And that the mind is like a garden. So when people say, ‘I did this,’ I always think to myself that it would be like a little lump of dirt saying to you, ‘Look at the flower I made.’ > >GC: I absolutely agree with you, David. I remember Benoit Mandelbrot was in a documentary as he was dying, and you could barely hear his voice – they had to put subtitles – and he was saying, ‘I discovered a beautiful world.’ > >It feels like it’s out there, and you feel very lucky to have stumbled on it. But I don’t think you can take the credit. It’s like climbing mountains: you climb a mountain to get a better view, to see further, and one always feels that there are other mountain ranges that are higher. In the distance you can see still higher mountains, and the ranges never stop and it always gets higher. The further you see, the more you realise that there are. > >So, for example, I’ve worked on Omega, but what is consciousness? What is the mind? How does the brain work? Can you prove that Darwinian evolution works? Where do new species come from? I mean, there’s endless questions, and each question just opens more questions. In a [[provocative paper titled "Mathematics on a Distant Planet"|http://worrydream.com/refs/Hamming%20-%20Mathematics%20on%20a%20Distant%20Planet.pdf]] by Richard Hamming [[he points out the criticality of mathematics to real life, but also points out some of its arbitrary and non-relevant parts|The (crucial) importance of mathematics]] (in his (learned!) opinion), and adds: >Hermite said, "We are not the master of Mathematics, we are the servant." I have often said the opposite, "We are the master of Mathematics, not the servant; it shall do as we want it to do." In truth, I seem to believe in a blend of the two remarks; at times we are driven and at times we are in control of mathematics. So too, the aliens will find themselves, and because they live in the same kind of physical world and have established radio contact with us, their "robust," useful mathematics will have a reasonable analogy with ours, but the "non-robust" parts could be very different. Would they even know or care about all of our trivial theorems? ---- ^^1^^ “The miracle of the appropriateness of the language of mathematics to the formulation of the laws of physics is a wonderful gift which we neither understand nor deserve.” - in Wigner's 1960 article [[The Unreasonable Effectiveness of Mathematics in the Natural Sciences|https://www.dartmouth.edu/~matc/MathDrama/reading/Wigner.html]]
IS THE INTERNET CHANGING THE WAY WE THINK? Copyright 2011 by [[Edge Foundation, Inc.|http://edge.org/]]
The Net's impact on our minds and future.
Edited by John Brockman
<<forEachTiddler
where
'tiddler.tags.contains("book-chapter") && tiddler.tags.contains("Is the Internet Changing the Way You Think?")'
sortBy
'tiddler.title'>>
[[Also by John Brockman and the Edge "cohort"|What Have You Changed Your Mind About?]]
a physicist and science fiction writer
It [evolution] was a concept of such stunning simplicity, but it gave rise, naturally, to all of the infinite and baffling complexity of life. The awe it inspired in me made the awe that people talk about in respect of religious experience seem, frankly, silly beside it. I'd take the awe of understanding over the awe of ignorance any day.
It goes against the grain of modern education to teach students to program. What fun is there to making plans, acquiring discipline, organizing thoughts, devoting attention to detail, and learning to be self critical.
It has been said that democracy is the worst form of government except all the others that have been tried.
It is a common illusion that something is wrong //because// we are sad, rather than that nothing is wrong //although// we are sad.
It is a fine thing to be honest, but it is also very important to be right.
It is by logic that we prove, but by intuition that we discover.
It's about Big Meaning, not Big Data.
Said [[Alan Kay|https://en.wikipedia.org/wiki/Alan_Kay]] (a "[[CS Sage|https://en.wikipedia.org/wiki/List_of_computer_scientists]]") in a talk which opens with his thoughts on "Big Data":
>Big data is a way that a lot of people are trying to make money today. And it's a favorite of marketing people, because it's in the wind. Everybody has heard the phrase “big data.” Not everybody knows what it means. And so it's the perfect context for doing things that people can say, “Well, this is an application of big data and this is an application of big data.” But in fact, the interesting future's not about data at all—it's about meaning.
[[Kay commented on it|https://news.ycombinator.com/item?id=11803165]] later saying:
> the real issues are not "big data" but "big understanding", not "Machine Learning" but "Machine Thinking". [...T]he "[[Dream Machine|http://www.nytimes.com/2001/10/07/books/review/07PAULOST.html]]" [ [[book|https://www.amazon.com/Dream-Machine-Licklider-Revolution-Computing/dp/014200135X]] ] is about how the funders were willing to put forth considerable resources for "problem finding" not just "problem solving" -- a lot more of that needs to be done today.
You can watch the whole [[TED Talk: The Future Doesn't Have to Be Incremental|https://www.youtube.com/watch?v=gTAghAJcO1o]] (on ~YouTube)
In [[another TED Talk|http://ed.ted.com/lessons/the-rise-of-human-computer-cooperation-shyam-sankar]] Shyam Sankar, said: "it's not a question of //how// to cmpute [things], but //what// to compute". His point was that you have to include the humans and human values in the picture.
In a recent NPR broadcast covering the [[Edge question of which scientific idea is ready for retirement|https://www.edge.org/conversation/john_brockman-this-idea-must-die-scientific-theories-that-are-blocking-progress]], one of the scientists brought up the work done by astronomers Tycho Brahe and Johannes Kepler about the orbits of the planets.
Tycho was the meticulous data collector of observations of planet positions in the sky and Kepler was the brilliant analyzer and interpreter of the data.
As [[an article at Harvard|http://chandra.harvard.edu/edu/formal/icecore/The_Astronomers_Tycho_Brahe_and_Johannes_Kepler.pdf]] put it:
>Tycho was a scientist who worked by direct observation. Kepler was a scientist who worked by calculation and testing one idea after another. Tycho's life's work of measuring the positions of objects in the sky was in itself useless without someone like Kepler to come along and make sense of those measurements. In the same way, Kepler's efforts to understand how the planets moved would be nothing but speculation, guessing, and mysticism if he did not have the basic data – the accurate measurements made by Tycho – against which to test his ideas and theories. Each one’s work is meaningful because of the work of the other.
[>img[Kepler's Laws|resources/Kepler Laws 1.png][resources/Kepler Laws.png]]
Kepler came up with his [[famous 3 Laws of planetary motion|https://en.wikipedia.org/wiki/Kepler%27s_laws_of_planetary_motion]]:
1. The orbit of a planet is an ellipse with the Sun at one of the two foci.
2. A line segment joining a planet and the Sun sweeps out equal areas during equal intervals of time.
3. The square of the orbital period of a planet is proportional to the cube of the semi-major axis of its orbit.
It is quite feasible to take Tycho's Big Data (all his meticulous observations) and come up with Law #1 above (elliptical orbits) and Law #3 (proportional ratios). But the point the scientist made was that he saw no way for Big Data Analysis to come up with Law #2 (equal areas). This idea takes a "qualitative jump" which no amount of data collection and analysis can trigger or produce.
[>img[Alan Kay's New Ideas Plane|resources/Alan Kay New Plane 1.png][resources/Alan Kay New Plane.png]]
[[Alan Kay pictures it|https://www.youtube.com/watch?v=gTAghAJcO1o]] as a move ("jump")^^1^^ taking us to a different (perpendicular) plane or dimension^^2^^, which quantities of data and data analysis alone cannot produce.
And on a personal note, related to teaching and learning, why is this difference important? I think that it is vital to not only teach how to "do big data" (collection, management, analysis), but even more importantly we need to teach (as much as it's possible) to "do meaning generation".
----
^^1^^ See also [[AHA! Moments]]
^^2^^ David Darling, in his book //Zen Physics// talks about explanatory issues with quantum mechanics and the interpretation and understanding required, and describes this [[intuitive jump or transition|Zen Physics, meaning and understanding]] which takes us into a different plane.
In the (very) witty and (sometimes) wise book "The Phantom Tollbooth" by Norton Juster^^1^^, he has a great chapter (ch. 9) about points of view and perspective. I think that it emphasizes (and embodies :) the point (of view :) that the "[[CS Sage|https://en.wikipedia.org/wiki/List_of_computer_scientists]]" Alan Kay was making when he quipped: >[[A good point of view is worth many IQ points]]. In this chapter, the boy Milo (the protagonist) and his companions, the ticking dog (a watchdog named Tock) and the Humbug, meet a curious boy (Alec) who is literally floating in the air. Alec claims that All Depends on How You Look at Things (which is a philosophically astute observation, come to think of that!). >"For instance," continued the boy, "if you happened to like deserts, you might not think this [lush forest scenery] was beautiful at all." >"That's true," said the Humbug, who didn't like to contradict anyone whose feet were that far off the ground. >"For instance," said the boy again, "if Christmas trees were people and people were Christmas trees, we'd all be chopped down, put up in the living room, and covered with tinsel, while the trees opened our presents." >"What does that have to do with it?" asked Milo. >"Nothing at all," he answered, "but it's an interesting possibility, don't you think?" (don't these "pointless asides" remind you of some of Lewis Carroll's Alice dialogs?) >"How do you manage to stand up there?” asked Milo, for this was the subject which most interested him. >“I was about to ask you a similar question," answered the boy, "for you must be much older than you look to be standing on the ground." >“What do you mean?” Milo asked. >"Well," said the boy, "in my family everyone is born in the air, with his head at exactly the height it's going to be when he's an adult, and then we all grow toward the ground. When we're fully grown up or, as you can see, grown down, our feet finally touch. Of course, there are a few of us whose feet never reach the ground no matter how old we get, but I suppose it's the same in every family." And talking about "normal childhoods", and "(im)possible feats", from the inimitable Carroll (Through the Looking Glass, Alice and the White Queen): >>[The Queen:] "I'm just one hundred and one, five months and a day." >>"I can't believe that!" said Alice. >>"Can't you?" the Queen said in a pitying tone. "Try again: draw a long breath, and shut your eyes." >>Alice laughed. "There's no use trying," she said: "one can't believe impossible things." >>"I daresay you haven't had much practice," said the Queen. "When I was your age, I always did it for half-an-hour a day. Why, sometimes I've believed as many as six impossible things before breakfast." And back to Juster: >He hopped a few steps in the air, skipped back to where he started, and then began again. >"You certainly must be very old to have reached the ground already." >"Oh no,” said Milo seriously. "In my family we all start on the ground and grow up, and we never know how far until we actually get there." >"What a silly system.” The boy laughed. “Then your head keeps changing its height and you always see things in a different way? Why, when you're fifteen things won't look at all the way they did when you were ten, and at twenty everything will change again.” >"I suppose so," replied Milo, for he had never really thought about the matter. >“We always see things from the same angle,” the boy continued. “It's much less trouble that way. Besides, it makes more sense to grow down and not up. When you're very young, you can never hurt yourself falling down if you're in mid-air, and you certainly can't get into trouble for scuffing up your shoes or marking the floor if there's nothing to scuff them on and the floor is three feet away.” >"That's very true," thought Tock, who wondered how the dogs in the family liked the arrangement. > >"But there are many other ways to look at things," remarked the boy. >"For instance, you had orange juice, boiled eggs, toast and jam, and milk for breakfast," he said, turning to Milo. “And you are always worried about people wasting time,” he said to Tock. “And you are almost never right about anything,” he said, pointing at the Humbug, "and, when you are, it's usually an accident.” >"A gross exaggeration," protested the furious bug, who didn't realize that so much was visible to the naked eye. >“Amazing,” gasped Tock. "How do you know all that?” asked Milo. >"Simple," he said proudly. "I'm Alec Bings; I see through things. I can see whatever is inside, behind, around, covered by, or subsequent to anything else. In fact, the only thing I can't see is whatever happens to be right in front of my nose." >“Isn't that a little inconvenient?” asked Milo, whose neck was becoming quite stiff from looking up. >“It is a little,” replied Alec, “but it is quite important to know what lies behind things, and the family helps me take care of the rest. My father sees to things, my mother looks after things, my brother sees beyond things, my uncle sees the other side of every question, and my little sister Alice^^1^^ sees under things." >“How can she see under things if she's all the way up there?” growled the Humbug. >"Well," added Alec, turning a neat cartwheel, "whatever she can't see under, she overlooks." What and amazing family! >"Would it be possible for me to see something from up there?” asked Milo politely. >"You could,” said Alec, “but only if you try very hard to look at things as an adult does." >Milo tried as hard as he could [Alice and the White Queen again^^1^^], and, as he did, his feet floated slowly off the ground until he was standing in the air next to Alec Bings. He looked around very quickly and, an instant later, crashed back down to earth again. >"Interesting, wasn't it?" asked Alec. >“Yes, it was,” agreed Milo, rubbing his head and dusting himself off, “but I think I'll continue to see things as a child. It's not so far to fall." [better safe then sorry; take advantage or enjoy what you have and where you are :) ] >“A wise decision, at least for the time being,” said Alec. "Everyone should have his own point of view." >“Isn't this everyone's Point of View?” asked Tock, looking around [the Vista Point (ha!) they all stand at] curiously. > >“Of course not,” replied Alec, sitting himself down on nothing. “It's only mine, and you certainly can't always look at things from someone else's Point of View. For instance, from here that looks like a bucket of water,” he said, pointing to a bucket of water; “but from an ant's point of view it's a vast ocean, from an elephant's just a cool drink, and to a fish, of course, it's home. So, you see, the way you see things depends a great deal on where you look at them from. Now, come along and I'll show you the rest of the forest." >He ran quickly through the air, stopping occasionally to beckon Milo, Tock, and the Humbug along, and they followed as well as anyone who had to stay on the ground could. >"Does everyone here grow the way you do?” puffed Milo when he had caught up. >“Almost everyone,” replied Alec, and then he stopped a moment and thought. “Now and then, though, someone does begin to grow differently. Instead of down, his feet grow up toward the sky. But we do our best to discourage awkward things like that." >"What happens to them?” insisted Milo. >"Oddly enough, they often grow ten times the size of everyone else," said Alec thoughtfully, “and I've heard that they walk among the stars.” And with that he skipped off once again toward the waiting woods. ---- ^^1^^ - This book/story has multiple common things and similarities on multiple levels with Lewis Carroll's books "Alice in Wonderland" and "Through the Looking Glass".
This semester I volunteered to teach another course^^1^^ for [[Citizen Schools|http://www.citizenschools.org/california/]], this time in Campbell Middle School. I decided to reteach the [[Amazing Mazes course|The "Amazing Mazes" course]], with the goal of tweaking the curriculum and lesson plans (see [[course outline, lesson plans, and student activities/programs|http://employees.org/~hmark/courses/amazingmazes/index.html]]) so that they could be added to the [[Citizen Schools' national STEM curriculum repository|http://www.citizenschools.org/curriculum-category/science-technology/]]^^2^^.
The Citizen Schools national STEM curriculum has a couple of courses combining game design, programming and math, but I wanted to provide an alternative course which I believe strikes a better balance between these elements, and ties more strongly into the wider context of [[Computational Literacy and Thinking|A Framework for Computational Thinking, Computational Literacy]].
These are some of the new and revised elements of the course:
!!!Computational Literacy and Computational Thinking
[>img[A Framework for Computational Thinking, Computational Literacy|resources/Computational Thinking process-small.png][A Framework for Computational Thinking, Computational Literacy]]
* Levels of abstraction
** Describing, designing, and manipulating mazes and walkers
* Modeling and representation
** Networking equivalence, programs and algorithms
* Algorithms and procedures
** Strategies and algorithms for solving/walking mazes
* Automation
** Commands, loops, conditions, programs
!!!Support for Teachers and Teaching Fellows
[>img[Amazing Mazes maze programming|resources/Wikispaces-AmazingMazes-teachers-small.png][resources/Wikispaces-AmazingMazes-teachers.png]]
In addition to the detailed lesson plans below, I have also created [[a secure wiki "by teachers, for teachers" on Wikispaces|http://computationalliteracy.wikispaces.com/]], to enable the development of a community around this course. This wiki for teachers includes a web-based copy of each lesson plan, a PDF version for printing, and a Microsoft Word copy for editing/modifying each lesson. It also includes a discussion board for the course as well as for each lesson, where teachers can post comments, tips & tricks, etc. There is a section for various relevant resources relevant to the course, such as articles, video clips, worksheets with examples and problems, etc.
I have leveraged Wikispaces' ability to create and link different spaces together, to create a student space too, and link it to the teachers' space. This way, the teachers can go back and forth between the [["teacher view"|resources/Wikispaces-AmazingMazes-teachers.png]] * and the [["student view"|resources/Wikispaces-AmazingMazes-students.png]] **, and review the collection of Java applets (programs) for creating mazes and programming maze walkers, and the various other resources and activities that students will be using.
{{{*}}} Secure access to the [[Wikispaces teachers' view|http://computationalliteracy.wikispaces.com/-/Amazing%20Mazes/AmazingMazes%20teachers/]]
{{{**}}} Secure access to the [[Wikispaces students' view|http://computationalliteracy.wikispaces.com/-/Amazing%20Mazes/AmazingMazes%20students/]]
!!!The course outline
At a high level, the course outline consists of several parts:
* Introduction to mazes
** Types, characteristics, complexities
* Designing and building mazes
** Manual and programmatic creation of mazes
* Solving mazes
** viewing perspectives, manual traversals, search/walking algorithms
* Maze walker programming
** From simple to complex algorithms
* Evaluation
** Maze walker program effectiveness (correctness), and efficiency (speed)
!!!The lesson plans
[[Lesson 1|resources/Amazing Mazes - lesson 1.pdf]] - Introduction to mazes
[[Lesson 2|resources/Amazing Mazes - lesson 2.pdf]] - Introduction to maze building (manual)
[[Lesson 3|resources/Amazing Mazes - lesson 3.pdf]] - How to build a maze (programming)
[[Lesson 4|resources/Amazing Mazes - lesson 4.pdf]] - Introduction to maze walker programming
[[Lesson 5|resources/Amazing Mazes - lesson 5.pdf]] - Maze walker programming
[[Lesson 6|resources/Amazing Mazes - lesson 6.pdf]] - Maze walking algorithms
[[Lesson 7|resources/Amazing Mazes - lesson 7.pdf]] - Programming loops and conditions 1
[[Lesson 8|resources/Amazing Mazes - lesson 8.pdf]] - Programming loops and conditions 2
[[Lesson 9|resources/Amazing Mazes - lesson 9.pdf]] - Advanced walker programming
[[Lesson 10|resources/Amazing Mazes - lesson 10.pdf]] - Display and presentation
The detailed lesson plans are referring to [[the students' programs and activities|courses/amazingmazes/index.html]].
----
^^1^^ The original Amazing Mazes course at [[MIT|http://www.citizenschools.org/california/about/locations/]] was [["Amazing Mazes"|The "Amazing Mazes" course]].
Another course I did was [["Acing Racing"|The "Acing Racing" course]]
And another course I did was [["Right on Target"|The "Right on Target" course]]
^^2^^ STEM = Science, Technology, Engineering, Mathematics
From a [[blogpost at BrainPickings|https://www.brainpickings.org/2014/04/21/jerome-bruner-on-knowing-left-hand-creativity/]], reviewing Jerome Bruner's book "On Knowing: Essays for the Left Hand". The title of the book comes from Bruner’s childhood fascination with the symbolism of the right hand as the doer and the left as the dreamer, and it is this toxic divide between the two that he sets out to counter with equal parts insight and irreverence. Articulating and lamenting how the artificial divide between intuition and intelligence limits us, Bruner pits himself “in the role of a would-be mediator between the humanist and the scientist” and gently guides the metaphoric left hand to tickle the right, which has become “too stiff with technique,” into creative awakening. In his book he writes: >I end with the same perplexity in attempting to find some way of thinking reasonably about the creative process. At the outset I proposed that we define the creative act as effective surprise — the production of novelty. It is reasonable to suppose that we will someday devise a proper scientific theory capable of understanding and predicting such acts. Perhaps we will understand the energies that produce the creative act much as we have come to understand how the dynamo produces its energy. It may be, however, that there is another mode of approach to knowing how the process generates itself, and this will be the way in which we understand how symbols and ideas … capture [our] thoughts. Often it is the poet who grasps these matters most firmly and communicates them most concisely. Perhaps it is our conceit that there is only one way of understanding a phenomenon. I have argued that just as there is predictive effectiveness, so is there metaphoric effectiveness. For the while, at least, we can do worse than to live with a metaphoric understanding of creativity. Bruner proposes six essential conditions of creativity: # ''Detachment and commitment''. A willingness to divorce oneself from the obvious is surely a prerequisite for the fresh combinatorial act that produces effective surprise. there must be as a necessary, if not a sufficient, condition a detachment from the forms as they exist… But it is a detachment of commitment. For there is about it a caring, a deep need to understand something, to master a technique, to render a meaning. So while the poet, the mathematician, the scientist must each achieve detachment, they do it in the interest of commitment. And at one stroke they, the creative ones, are disengaged from that which exists conventionally and are engaged deeply in what they construct to replace it. # ''Passion and decorum''. By passion I understand a willingness and ability to let one’s impulses express themselves in one’s life through one’s work… Passion, like discriminating taste, grows on its use. You more likely act yourself into feeling than feel yourself into action… But again a paradox: it is not all urgent vitality. There is decorum in creative activity: a love of form, an etiquette toward the object of our efforts, a respect for materials… So both are necessary and there must surely be a subtle matter of timing involved — when the impulse, when the taming. # ''Freedom to be dominated by the object''. [For example, in The Arts] You begin to write a poem. Before long it, the poem, begins to develop metrical, stanzaic,symbolical requirements. You, as the writer of the poem, are serving it — it seems. Or [for example in The Sciences] you may be pursuing the task of building a formal model to represent the known properties of single nerve fibers and their synapses: soon the model takes over… There is something odd about the phenomenon. We externalize an object, a product of our thoughts, treat it as “out there.” Freud remarked, commenting on projection, that human beings seem better able to deal with stimuli from the outside than from within. So it is with the externalizing of a creative work, permitting it to develop its own being, its own autonomy coming to serve it. It is as if it were easier to cope with there, as if this arrangement permitted the emergence of more unconscious impulse, more material not readily accessible… To be dominated by an object of one’s own creation — perhaps its extreme is Pygmalion dominated by Galatea — is to be free of the defenses that keep us hidden from ourselves. # ''Deferral and immediacy''. There is an immediacy to creating anything, a sense of direction, an objective, a general idea, a feeling. Yet the immediacy is anything but a quick orgasm of completion. Completion is deferred… It is the boredom of conflict, knowing deep down what one wishes to say and knowing that one has not said it. one acts on the impulse to exploit an idea, to begin. One also acts on the impulse of boredom, to defer. # ''The internal drama''. There is within each person his own cast of characters* — an ascetic, and perhaps a glutton, a prig, a frightened child, a little man, even an onlooker, sometimes a Renaissance man. The great works of the theater are decompositions of such a cast, the rendering into external drama of the internal one, the conversion of the internal cast into dramatis personae… It is the working out of conflict and coalition within the set of identities that compose the person that one finds the source of many of the richest and most surprising combinations. It is not merely the artist and the writer, but the inventor too who is the beneficiary. # ''The dilemma of abilities''. What shall we say of energy, of combinatorial zest, of intelligence, of alertness, of perseverance? I shall say nothing about them. They are obviously important but, from a deeper point of view, they are also trivial. For at any level of energy or intelligence there can be more or less of creating in our sense. Stupid people create for each other as well as benefiting from what comes from afar. So too do slothful and torpid people. I have been speaking of creativity, not of genius.
A German writer, pictorial artist, biologist, theoretical physicist, and polymath.
<<list-links "[tag{!!title}]">>
Publisher & Editor, [[Edge|http://www.edge.org]]
American novelist, essayist, literary critic and university professor.
([[A different, but related take on questions|David Whyte - questions]] is given by [[David Whyte|http://www.davidwhyte.com/]], who [[John O'Donohue|https://www.johnodonohue.com/]] knew). >All thought is about putting a face on experience… One of the most exciting and energetic forms of thought is the question. I always think that the question is like a lantern. It illuminates new landscapes and new areas as it moves. Therefore, the question always assumes that there are many different dimensions to a thought that you are either blind to or that are not available to you. So a question is really one of the forms in which wonder expresses itself. One of the reasons that we wonder is because we are limited, and that limitation is one of the great gateways to wonder. : -- from the transcript of //Walking on the Pastures of Wonder: John O’Donohue in Conversation with John Quinn// and as Oliver Wendell Holmes had said: [[Man's mind, once stretched by a new idea, never regains its original dimensions.]]
former Chief Scientist of Xerox Corporation and former director of the Xerox Palo Alto Research Center (PARC)
Type the text for 'John Steinbeck'
A psychological study was conducted to learn more about traits and characteristics of various professionals, giving a physicist, a business person, and a mathematician the following problem to solve: a few cows are grazing in a meadow. Given a roll of chain fence, what is the shortest fence you need in order to contain all cows inside of it? The physicist started by plotting the location of all cows on graph paper, connecting all outlying cows with straight lines, and declaring that since the closed shape is convex, it is the shortest path and therefore the shortest fence possible. The business person became angry at the waste of materials, slapped the physicist and declared he'll show everyone what the shortest fence is. He fixed one end of the fence to a poll in the meadow, and started rolling out the chain fence, while rounding up the cows into a tight group around the poll until they were all squeezed together, at which point he closed the fence, and announced that //this// is the shortest fence possible. Meanwhile, the mathematician got lost in thought, and when he had been "brought back to earth" by the business person, declared that the problem was not well defined. The business person threatened to slap the mathematician if he did not proceed, so the mathematician cut a very short segment of the chain fence, wrapped it around //himself// and announced: "I'm outside".
A French moralist and essayist. Born 7 May 1754 in Montignac, Perigord, died 4 May 1824 in Paris.
In his book [[The Most Human Human - by Brian Christian]] he write: >It's an odd thing, this: we often think of therapy as intimate, a place to be understood, profoundly understood, perhaps better than we ever have been. The controversial psychologist/therapist Richard Bandler says: >“I think it's extremely useful for you to behave so that your clients come to have the illusion that you understand what they are saying verbally," he says. “I caution you against accepting the illusion for yourself.” And (as a response to this?), Weizenbaum wrote a piece titled //Supplanted by Pure Technique//: >I had thought it essential, as a prerequisite to the very possibility that one person might help another learn to cope with his emotional problems, that the helper himself participate in the other's experience of those problems and, in large part by way of his own empathic recognition of them, himself come to understand them. >There are undoubtedly many techniques to facilitate the therapist's imaginative projection into the patient's inner life. But that it was possible for even one practicing psychiatrist [Bandler] to advocate that this crucial component of the therapeutic process be entirely supplanted by pure technique—that I had not imagined! What must a psychiatrist who makes such a suggestion think he is doing while treating a patient, that he can view the simplest mechanical parody of a single interviewing technique as having captured anything of the essence of a human encounter? and Christian continues: >Pure technique, Weizenbaum calls it. This is, to my mind, the crucial distinction. “Man vs. machine" or "wetware vs. hardware” or “carbon vs. silicon”-type rhetoric obscures what I think is the crucial distinction, which is between method and method's opposite: which I would define as judgment," "discovery," "figuring out," and, "site-specificity." >We are replacing people not with machines, nor with computers, so much as with method. And whether it's humans or computers carrying that method out feels secondary. >[...] What we are fighting for, in the twenty-first century, is the continued existence of conclusions not already foregone -- the continued relevance of judgement and discovery and figuring out, and the ability to continue to exercises them. I agree with Weizenbaum that in many areas we are and will continue to replace many traditionally perceived/thought off human behaviors/traits with techniques/machines. This has been happening as part of human evolution, and the "trick" is to wisely choose the path and dividing line between traits and characteristics "essential" to human nature and self-definition, and things which are not "human defining" and at the core of humanness. But/And as Josue Harari and David Bell say: >The term method itself is problematic because it suggests the notion of repetition and predictability—a method that anyone can apply. Method implies also mastery and closure, both of which are detrimental to invention. Here, again, some things are worth replacing with a method/technique, but some are not. In my mind, to be human means to need and want both mastery/closure //and// innovation/discovery. As Alfred North Whitehead wrote (in "An Introduction to Mathematics"): >It is a profoundly erroneous truism, repeated by all the copybooks, and by eminent people when they are making speeches, that we should cultivate the habit of thinking what we are doing. The precise opposite is the case. Civilization advances by extending the number of operations which we can perform without thinking about them. Operations of thought are like cavalry charges in a battle -they are strictly limited in number, they require fresh horses, and must only be made at decisive moments. I think that redefining what is "characteristically human" is (and should be) an on-going process. We are alive and evolving, and so does and should our self-image/definition. As Claude Shannon said: >Chess is generally considered to require "thinking" for skillful play; a solution of this problem [i.e., having computer play skillfully] will force us either to admit the possibility of a mechanized thinking or to further restrict our concept of "thinking". I'm not sure I'd use the work ''restrict'' here, but rather ''evolve''. In my mind this is analogous to what we/mathematicians had to do to the definition of ''number'' as we/they discovered irrational numbers, imaginary numbers, transcendental numbers, the [[infitesimals|Infinitesimals are significant (and meaningful?)]], etc. As it turns out, this evolution (or expansion) had significantly enriched and expanded math and human's experience of (and capabilities working with) it.
[[Joy Williams on Wikipedia|https://en.wikipedia.org/wiki/Joy_Williams_(American_writer)]]
Evangelist of "eXtreme Programming" (agile software development methodology)
It is true that you have to know how to read, and [[my father had a great personal story about it|Testing, Testing, 1, 2, 3 (or, you have to know how to read)]], but it turns out that there is more than one way to do it :) I realized it quite a few years back, on a bus ride in Israel. After I had boarded the bus and settled down, I noticed that the person sitting a couple of seats in front of me, on the other side of the isle, was reading a (Hebrew) newspaper. Nothing special about that, //except//, he was holding the newspaper upside down! He was a middle aged Yemeni Jew, and since I was sitting behind him I could not tell if he was actually "reading" the paper. A few thoughts went through my mind: Maybe he dosed off holding the paper upside down, or maybe he is just in the process of turning a page, or he is going to tear off a piece. But as I kept observing him, he actually went through all the motions of a regular/normal paper reader, turning pages, scanning articles, and so on, but the funny thing was that he scanned the pages from bottom to top and from left-to-right (instead of the normal right-to-left in Hebrew). And, he spend a long time on articles and pages, which led me to believe that he is not pulling a prank, but actually reading the paper! Recently, I found a corroboration/explanation in the book //The Puzzle of Left-handedness// by Rik Smits: >In April 1949 a remarkable photograph cropped up in various places around the World, showing a group of Yemeni Jews in a reception camp near the seaport of Aden. They are on their way to Israel and they're all crowding around a Torah. >One has the book in front of him in such a way that he can read it in the normal Hebrew manner from right to left, in lines that run from top to bottom. >A second is sitting off to the left of the Torah and is therefore forced to read columns of text that run from top to bottom and from left to right. >In the foreground another man is reading the text upside down and the rest too, from various angles, are doing their best to look at the pages. > >It's difficult for people in the rich world to imagine, but clearly these gentlemen are at ease with their unconventional reading positions. A scarcity of books [in Yemen], such that one copy had to be shared between three or four schoolchildren, had caused them to learn to read from various angles. >Why not, in fact? There's no law of nature that says, for example, that our letter A must stand with two feet on the ground; in fact, there was once a time when it didn't. Originally, in the Phoenician alphabet, it was upside down, forming a pictogram of an ox's head with horns. Later it came to lie on its side and only when the Greeks adopted it did the two 'horns' come to rest on the ground. >We may Wonder how the men in the photograph wrote, assuming they had learned to do so. Did they orientate themselves in the same way as for reading, or did they write in the standard Hebrew manner, in horizontal lines from right to left? Did this affect how well they could write? So, puzzle solved, and reading, one way (or four) or another, is better than not reading at all. (and on a more serious (and practical :) note, see [[A Helpful Guide to Reading Better - Farnam Street]])
Paul Lockhart in his book [["A Mathematician's Lament"|file:///Users/hmark/Downloads/tiddlywikis/resources/LockhartsLament.pdf]] writes: ...once we know //why// something is true, then in particular we know //that// it is true.A trillion instances tell us nothing; when it comes to infinity, the only way to know what is to know why. Proof is our way of capturing an infinite amount of information in a finite way. That's really what it means for something to have a pattern -- if we can capture it with //language//.
Knowledge is one. Its division into subjects is a concession to human weakness.
Type the text for 'language'
writer of Science Fiction books (e.g. Protector)
[[Lauren Ipsum|http://www.laurenipsum.org/sample]] by Carlos Bueno looks like a great book about Computer Science (for ordinary mortals^^1^^ and children of all ages). Just the introduction makes you want to read it, since it hits the nail on the head about what CS is all about. Hint: it echos the (anonymous) saying that >Computer science is no more about computers (or programming languages) than astronomy is about telescopes. and the point that [[Alan Kay|https://en.wikipedia.org/wiki/Alan_Kay]] (a "[[CS Sage|https://en.wikipedia.org/wiki/List_of_computer_scientists]]") makes, that >Computers are to computing as instruments are to music." >No computers will be found in this book. If the idea of a computer science book without computers upsets you, please close your eyes until you’ve finished reading the rest of this page. >The truth is that computer science is not really about the computer. It is just a tool to help you see ideas more clearly. You can see the moon and stars without a telescope, smell the flowers without a fluoroscope, have fun without a funoscope, and be silly sans oscilloscope. >You can also play with computer science without... you-know-what. Ideas are the real stuff of computer science. This book is about those ideas, and how to find them. ---- ^^1^^ referring to the book //[[Computing for Ordinary Mortals|https://global.oup.com/academic/product/computing-for-ordinary-mortals-9780199775309?cc=us&lang=en&]]// by [[Robert St. Amant|http://www4.ncsu.edu/~stamant/]] (a CS professor at North Carolina State University), who also wrote [[a very touching article|http://www.nytimes.com/2014/05/11/fashion/Modern-Love-Promises-That-Can-Bend-Without-Breaking.html]] in the New York Times (//Promises That Can Bend Without Breaking//) about his life with his wife and her deteriorating health.
In a short but [[interactive/demo-filled TEDx Talk|http://ww2.kqed.org/mindshift/2013/10/22/learn-to-code-code-to-learn/]], [[Mitch Resnick|https://www.media.mit.edu/people/mres]] from the [[Scrtach|https://scratch.mit.edu/]] development team at MIT, made some excellent points about why is it important to learn to code. Resnick also has [[an assay|https://www.edsurge.com/n/2013-05-08-learn-to-code-code-to-learn]] along the same lines on the MIT site. Here are the key ideas I have captured from the video: * Learning to code makes you ''fluent'' with new technologies. Resnick defines "fluent" as the ability of someone to express themselves and their ideas. He makes an analogy to language fluency, which means (among other things) that you can write well and express ideas, feelings, tell jokes, write essays, etc. * Resnick makes a distinction between technology fluency and ''technology use''. He includes in the latter category things like browsing, chatting, texting, gaming. All of these are (good and useful) forms of __interacting__ with new technologies, but these don't necessarily make you __fluent__ with these technologies. Drawing on his previous analogy, he says that "it's as if [young users] can read but not write with these new technologies". * If we want to make users "fluent with new technologies" we need to teach them how to "write in/for those new technologies" which means, we have to teach them to code! * When people learn to code, they are able to code to learn, which means that as they learn to code it enables them to code and learn _other_, and __new__ things. In other words, coding opens up opportunities to learn other things. This is similar to learning how to read, which then enables you to read in order to learn (new/other things). * In addition to coding teaching you some obvious things like how the computer works, and so on, it also teaches you some important skills for life, like: ** how to take an idea and get it through the design process to a working product. ** how to experiment with new ideas and assess their value ** how to break up a complex problem into smaller, more manageable parts ** how to debug problems, which involves coming up with theories, setting up experiments, analyzing data ** how to deal with frustration, develop perseverance, stick with things for the long haul ** how to work collaboratively, how to ask/receive help and how to give/provide help * Most people learning how to code will probably not become professional computer scientists or programmers. But this is similar to the fact that most people who learn to read and write will not become professional writers or authors. * So, again, learning to be fluent with new technologies requires learning to code, which in turn enables you to code in order to learn, as well as express yourself and be creative.
A father visited the college where he had been a science student, and where his daughter was now a science student. They happened to encounter a science professor who some twenty years earlier had taught the father and who last year had taught the daughter. The father said, sincerely, that he had greatly enjoyed the professor's course and that his daughter had recently raved to him about the course, but he confessed that he was greatly disappointed in one respect. "The questions on the examination you gave to my daughter's class were exactly the same as the ones you gave to my class twenty years ago.” “Ah, yes," the professor explained, “the questions are the same, but we have changed the answers." And another (possibly true, real-life) story: Every year, a distinguished professor at a medical school^^1^^ begins his lectures by telling his students, “Half of what we are teaching you will, in twenty years, be disproved. The trouble is, we don't know which half." ---- ^^1^^ - but even in the humanities and in the social sciences it is evident that things change, that throughout history, new knowledge makes us [[look differently|After The Fact - In the history of truth, a new chapter begins]] at the works and issues of society.
In an [[article about Learning and Teaching Programming|http://www.tandfonline.com/doi/pdf/10.1076/csed.13.2.137.14200]],^^1^^ Anthony Robins , Janet Rountree, and Nathan Rountree make some good observation about students and teachers of Computer Science, and provide some good insights and suggestions for teaching and learning. !!!! On Experts Versus Novices * the general consensus is (Winslow, 1996) that it takes about 10 years of study and experience to turn a novice to an expert. * they (Dreyfus and Dreyfus, 1986) distinguish between several levels of performance: ** novice, advanced beginner, competent, proficient, and expert. * they note that experts: ** have efficiently organised and specialised knowledge schemas; ** organise their knowledge according to functional characteristics such as the nature of the underlying algorithm (rather than superficial details such as language syntax); ** use both general problem solving strategies (such as divide-and-conquer) and specialised strategies; ** use specialised schemas and a top-down, breadth-first approach to efficiently decompose and understand programs; ** and are flexible in their approach to program comprehension and their willingness to abandon questionable hypotheses. ** Expert knowledge schemas also have associated testing and debugging strategies. * Rist, 1995 summarizes: Expertise in programming should reduce variability in three ways: ** by defining the best way to approach the design task, ** by supplying a standard set of schemas to answer a question, ** and by constraining the choices about execution structure to the ‘best’ solutions. !!!! On Knowledge Versus Strategies * Davies (1993) distinguishes between programming knowledge (of a declarative nature, e.g., being able to state how a ‘‘for’’ loop works) and programming strategies (the way knowledge is used and applied, e.g., using a ‘‘for’’ loop appropriately in a program). ** This is a very important distinction which should guide a teacher and provide focus to what is taught. It is important to teach the what (knowledge) but also put a lot of emphasis on the how (strategy). *** for example, a teacher should teach about one dimensional arrays/lists/vectors as well as loops - this is knowledge. But the teacher should also cover how to use these to calculate the average of the array/list/vector using loops. And in the case of functional programming show how this can be done (strategy/schema) with functional iterators (e.g. maps). ** typical course and books on programming focus on knowledge and less on strategy, which is missing a big part of how to become an expert! !!!! On Comprehension Versus Generation * Good (advanced beginner, competent, proficient, and expert) programmers should be effective in both analyzing programs and synthesizing them. That's why I teach and test my students on both! ** The two types of skills/performance are: ''program comprehension'' (where given the text of a program subjects have to demonstrate an understanding of how it works), and those that focus on ''program generation'' (where subjects have to create a part of or a whole program to perform some task/solve some problem). * Brooks (1977, 1983) proposes a model for program comprehension, where the original problem domain (e.g., a ‘‘cargo-routing’’ problem), which is transformed and represented as values and structures in intermediate domains, and finally instantiated in the data structures and algorithms of a program in the programming domain. ** Brooks describes program comprehension as a ‘‘top-down’’ and ‘‘hypothesis-driven’’ process. Brooks suggested that rather than studying programs line by line, subjects (assumed to be ‘‘expert’’ programmers) form hypotheses based on high-level domain and programming knowledge. These hypotheses are verified or falsified by searching the program for markers/‘‘beacons’’ which indicate the presence of specific structures or functions. * Rist (1995) presents a comprehensive model of program generation (see also Rist, 1986a, 1986b, 1989, 1990). !!!! On Teaching Procedural Versus ~Object-Oriented (OO) Programming * There is no conclusive research evidence (Detienne, 1997) that teaching one paradigm/style of programming is "better" for comprehension and/or construction of programs. ** It turns out that experts use both OO and Procedural when engaged in programming * Similarly, Rist (1995) describes the relationship between plans (a fundamental unit of program design, as discussed above) and objects as ‘‘orthogonal’’. Plans and objects are orthogonal, because one plan can use many objects and one object can take part in many plans. (Rist, 1995, pp. 555–556) !!!! On Course Golas, Progress, and Teaching Suggestions * Linn and Dalbey (1989) propose a ‘‘chain of cognitive accomplishments’’ that should arise from ideal computer programming instruction. This chain of accomplishments forms a good summary of what could be meant by deep learning in introductory programming. This chain starts with ** the features of the language being taught. ** The second link is design skills, including templates (schemas/plans), and the procedural skills of planning, testing and reformulating code. ** The third link is problem-solving skills, knowledge and strategies (including the use of the procedural skills) abstracted from the specific language taught that can be applied to new languages and situations. * A major recommendation to emerge from the literature is that __instruction should focus not only on the learning of new language features, but also on the combination and use of those features, especially the underlying issue of basic program design__. ** From our experience [. . .] we conclude that students are not given sufficient instruction in how to ‘‘put the pieces together.’’ Focusing explicitly on specific strategies for carrying out the coordination and integration of the goals and plans that underlie program code may help to reverse this trend. (Spohrer & Soloway, 1989, pp. 412–413) * A further important suggestion is to __address the kinds of mental models which underlie programming__: ** Models are crucial to building understanding. __Models of control, data structures and data representation, program design and problem domain are all important__. If the instructor omits them, the students will make up their own models of dubious quality. (Winslow, 1996, p. 21) * Burton suggests that teachers keep in mind the distinctions between ‘‘what actually gets taught; what we think is getting taught; what we feel we’d like to teach; what would actually make a difference’’ (Burton, 1998, p. 54). !!!! On Alternative Methods and Curricula * __''Teaching Patterns'' __ - An important recommendation noted above is that instruction should address the underlying issue of basic program design, in particular the use of the schemas/plans which are the central feature of programming knowledge representation ** As Spohrer & Soloway (1989, p. 413) suggest: We are suggesting that students be given a whole new vocabulary for learning how to construct programs. ** For an analysis and overview of the use of pattern languages for teaching see Fincher (1999a), and for two recent descriptions of courses based on patterns see Reed (1998) and Proulx (2000). * __''Problem Based Learning''__ - Deek et al. (1998) describe a first year computer science course based on a problem solving model, where language features are introduced only in the context of the students’ solutions to specific problems. ** An extensive discussion of the practical issues involved in problem based learning, a description of problem based learning courses, and a 3-year longitudinal follow-up of students is described in Kay et al. (2000). ** However as noted (Section 3.3) by for example Winslow (1996) and Rist (1995), problem solving is necessary, but not sufficient, for programming. The main difficulty faced by novices is expressing problem solutions as programs. Thus the coverage of language features and how to use and combine them must remain an important focus. !!!! Summary and Implications * From [the authors'] point of view as teachers there is a distinction which is much more important than the one between novices and experts which has received so much attention in the literature. This is the distinction between effective and ineffective novices. ** Effective novices are those that learn, without excessive effort or assistance, to program. Ineffective novices are those that do not learn, or do so only after inordinate effort and personal attention. ** It may be productive, in an introductory programming course, to explicitly focus on trying to create and foster effective novices. In other words, rather than focusing exclusively on the difficult end product of programming knowledge, it may be useful to focus at least in part on the enabling step of functioning as an effective novice. * What underlying properties make a novice effective? How can we best turn ineffective novices into effective ones? A deeper understanding of both kinds of novices is required. ** The range of potentially relevant factors includes motivation, confidence or emotional responses, and aspects of general or specific knowledge, strategies, or mental models. * The authors suggest that the most significant differences between effective and ineffective novices relate to strategies rather than knowledge (since language-related knowledge is widely available in books and traditional courses). ---- ^^1^^ - [[local copy|resources/Robins - Learning and Teaching Programming A Review and Discussion.pdf]] of the article !!!!References - Brooks, R.E. (1977). Towards a theory of the cognitive processes in computer programming. International Journal of Man-Machine Studies, 9, 737–751. - Brooks, R.E. (1983). Towards a theory of the comprehension of computer programs. International Journal of Man-Machine Studies, 18, 543–554. - Davies, S.P. (1993). Models and theories of programming strategy. International Journal of Man-Machine Studies, 39, 237–267. - Deek, F.P., Kimmel, H., & McHugh, J.A. (1998). Pedagogical changes in the delivery of the first-course in computer science: Problem solving, then programming. Journal of Engineering Education, 87, 313–320. - Detienne, F. (1990). Expert programming knowledge: A schema based approach. In J.M. Hoc, T.R.G. Green, R. Samurc¸ay, & D.J. Gillmore (Eds.), Psychology of programming (pp. 205–222). London: Academic Press. - Fincher, S. (1999a). Analysis of design: An exploration of patterns and pattern languages for pedagogy. Journal of Computers in Mathematics and Science Teaching: Special Issue CS-ED Research, 18, 331–348. - Kay, J., Barg, M., Fekete, A., Greening, T., Hollands, O., Kingston, J., & Crawford, K. (2000). Problem-based learning for foundation computer science courses. Computer Science Education, 10, 109–128. - Proulx, V.K. (2000). Programming patterns and design patterns in the introductory computer science course. Proceedings of the thirty-first SIGCSE technical symposium on computer science education (pp. 80–84). New York: ACM Press. - Reed, D. (1998). Incorporating problem-solving patterns in CS1. SIGCSE Bulletin, 30, 6–9. - Rist, R.S. (1995). Program structure and design. Cognitive Science, 19, 507–562.
I came across [[an interesting book review|http://www.brainpickings.org/index.php/2013/05/13/dont-go-back-to-school-kio-stark/]] by [[Maria Popova|http://www.brainpickings.org/index.php/author/mpopova/]] about the book //Don't Go Back to School: A Handbook for Learning Anything// by [[Kio Stark|http://www.kiostark.com/]]. More about this in a minute.
When searching for [[Stark's website|http://www.kiostark.com/]], I came across [[an interview she had|http://techcrunch.com/2013/05/13/obamas-cto-gives-advice-on-how-learning-works-in-kio-starks-new-book-dont-go-back-to-school/]] with [[Harper Reed|https://harperreed.com/]] (Obama's CTO in the 2012 campaign), in which he talks about how he learned/learns:
>I love computers and I’ve always been around computers. I can’t really talk about education without talking about computers. I went to high school and I actually really loved it.
>...
>I did learn some coding concepts in college, but more importantly I figured out that I’m an experiential learner. I need to put my hands on things and really see them, and really chew on them. It was better to do it in a real context, where it mattered if I did it right.
and it struck a cord with me. I am also learning best when encountering a new/cool thing/technology/capability and coming up with "something real" (or a "good, made-up project") to work on, using that thing.
>All the programming languages I know (starting with Basic on a Sinclair, C, Java, Javascript/HTML/XML, Perl, Python, to name a few), except for Pascal - which I learned at university, way back when - I learned "on the job" and/or as part of needing/wanting to do an "interesting project".
Ditto, all the "educational software" I use (NetLogo, GeoGebra, MathSage/Mathematica, Scratch/Snap, EJS, to name a few) - see [[a more comprehensive list|http://www.employees.org/%7Ehmark/wiki.html#%5B%5BEducational%20Technologies%5D%5D]], and [[some implementation examples|http://www.employees.org/%7Ehmark/math/index.html]]
Anyway, back to Stark (and not going back to school ;-), she is saying:
>My research based on interviews with 100 independent learners revealed four facts shared by almost every successful form of learning outside of school:
> It isn’t done alone.
> For many professions, credentials aren’t necessary, and the processes for getting credentials are changing.
> The most effective, satisfying learning is learning that which is more likely to happen outside of school.
> People who are happiest with their learning process and most effective at learning new things — in any educational environment — are people who are learning for the right reasons and who reflect on their own way of learning to figure out which processes and methods work best for them.
The first point is definitely true, and is emphasized, or at least practiced more nowadays in schools (as I've seen it with my children) and at university (as I've seen it myself, when I enrolled in [[my Masters studies|http://ldtprojects.stanford.edu/%7Ehmark/index_stanford.html]]). When I studied in school and for my Bachelors degree, it was less prevalent/encouraged/practiced.
The fourth point is also definitely true, as it speaks to motivation, persistence, and progress/achievement (in the real sense, not in a form of externals like grades, praise, class progression, etc.!). Stark hit it spot on regarding the importance of "know thyself" when it comes to lifelong learning on your own:
>Learning your own way means finding the methods that work best for you and creating conditions that support sustained motivation. Perseverance, pleasure, and the ability to retain what you learn are among the wonderful byproducts of getting to learn using methods that suit you best and in contexts that keep you going. Figuring out your personal approach to each of these takes trial and error.
Another observation Stark makes about MOOCs (massive open online course) is also true from my personal experience:
>Simply put, ~MOOCs are designed to put teaching online, and that is their mistake. Instead they should start putting learning online. The innovation of ~MOOCs is to detach the act of teaching from physical classrooms and tuition-based enrollment. But what they should be working toward is much more radical — detaching learning from the linear processes of school.
A [[MOOC on How to Learn Math|http://online.stanford.edu/course/how-to-learn-math]] I have taken from Stanford University online, is really a linear combination of 5-15 minute mini-lectures (almost exclusively "talking head"), interspersed with 1-2 open-ended questions, some of which are peer-graded.
It often feels like the questions are "guardrails" designed to make sure the students are paying attention, and to keep them on track. But this is a topic for another post.
[[Chaim Gingold|http://levitylab.com/cog/]] gave a talk at Stanford ([[video, 45 minutes|https://youtu.be/rTGG6Alznpg?list=PL2rro4X-RbDHcaCl6x-WkjdFFOP6s_xQN]]), where he demo'd Earth Primer and shared his love of simulation as a tool for experiential engagement and learning.
In the talk he shared 10 design principles that guided him through the design of multiple, very successful games/products, like SimCity, [[Earth Primer|https://vimeo.com/116182914]], and Spore.
!!!!10 Design Principles
1. Combine showing, telling, and doing - since this promotes effective learning. it's all about the experiential engagement and all modes of engagement should be leveraged. ("I hear and I forget. I see and I believe. I do and I understand" - attributed to Confucius)
2. Share your enthusiasm and love for a topic. When a mathematician, geologist, historian, or any other expert engage in math, geology, history, and so on, they see things in ways that non-experts don't see. Experiential learning systems enable the sharing of love, excitement, and ways of seeing special things in a domain of knowledge. This is in contrast with "sugar coating" and "dressing up" a topic/domain which is believed to be boring and dry, in an effort to make it "palatable". It's really about finding and exposing the core and elements which make a topic or domain interesting and exciting, and exposing it in engaging ways to share that essence and beauty.
3. Think and design in terms of end-to-end experience. Design the learning environment or product not just for usability, but also for a sense of delight, wonder, surprise, curiosity. Think also in terms of pacing and the speed and means for moving users/learners through the experience and arousing and maintaining their engagement (delight, wonder, surprise, curiosity). This is a deep craft. And it's not "gamification" which takes the surface (superficial) elements of games and game design principles and applies them instrumentally in other, non-game contexts. This is looking at the deep structures and principles and using them to promote learning in a deep experiential way.
4. Don't lecture. Text is OK, but the order, quantity, and timing is very important. Feedback is important.
5. Account for multiple and different modes of engagement. Cater to different modes and moods of experience (poke-and-play, read-and-study-first, "cautious vs. playful", etc.). Design for collaborative and individual learning. Invite learners to engage through different "doors".
6. Use guided play. Balance between direction and openness, control and free exploration and play. Sandbox, and "calls to action" and guidance.
7. Harness the computational power of the computer. Use simulation to bring systems and phenomena to life!
8. Create a "phantom sensation of tactility" (that the user can sort-of "touch and feel" the experience), combining playfulness and control.
9. Segment the experience and topic into smaller pieces. Use templates for reuse of simulations, tools, frameworks. Combine one-off tools and techniques with templates and reusable content and techniques. You don't have to use just one big simulation/content mode.
10. Design for a strong sense of playfulness and deep experience.
!!!!Play Design vs. Game Design
Characteristics of games (from Jesper Juul, 2003):
- Fixed rules
- Variable outcomes
- Valorization of outcome
- Player effort
- Player attached to outcome
- Negotiable consequences
I recently re-read [[Herbert Simon|https://en.wikipedia.org/wiki/Herbert_A._Simon]]'s book [["The Sciences of the Artificial"|https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=2ahUKEwjkxJqR-4LiAhUTt54KHXoSDYkQFjAAegQIABAC&url=https%3A%2F%2Fmonoskop.org%2Fimages%2F9%2F9c%2FSimon_Herbert_A_The_Sciences_of_the_Artificial_3rd_ed.pdf&usg=AOvVaw31Ts9dGjJfzIw6Z7hF18qT]] where he mentions the [[Meno dialog|resources/Plato_the_Meno.pdf]] between Socrates and a slave (as told by Plato), supposedly demonstrating that what we call learning is actually just [[re-membering or re-discovering|Rediscovery]] what's hidden/latent in us from before ([[anamnesis|https://en.wikipedia.org/wiki/Anamnesis_%28philosophy%29]]^^1^^). Simon has a neat and compact description of and solution to the "paradox" presented in the Meno: >"A circle is the locus of all points equidistant from a given point." "To construct a circle, rotate a compass with one arm fixed until the other arm has returned to its starting point." > >It is implicit in Euclid that if you carry out the process specified in the second sentence, you will produce an object that satisfies the definition of the first. The first sentence is a state description of a circle; the second, a process description. > >These two modes of apprehending structures are the warp and weft of our experience. Pictures, blueprints, most diagrams, and chemical structural formulas are state descriptions. Recipes, differential equations, and equations for chemical reactions are process descriptions. The former characterize the world as sensed; they provide the criteria for identifying objects, often by modeling the objects themselves. The latter characterize the world as acted upon; they provide the means for producing or generating objects having the desired characteristics. > >The distinction between the world as sensed and the world as acted upon defines the basic condition for the survival of adaptive organisms. The organism must develop correlations between goals in the sensed world and actions in the world of process. When they are made conscious and verbalized, these correlations correspond to what we usually call means-ends analysis. Given a desired state of affairs and an existing state of affairs, the task of an adaptive organism is to find the difference between these two states and then to find the correlating process that will erase the difference. > >Thus problem solving requires continual translation between the state and process descriptions of the same complex reality. Plato, in the Meno, argued that all learning is remembering. He could not otherwise explain how we can discover or recognize the answer to a problem unless we already know the answer. > >Our dual relation to the world is the source and solution of the paradox. We pose a problem by giving the state description of the solution. The task is to discover a sequence of processes that will produce the goal state from an initial state. Translation from the process description to the state description enables us to recognize when we have succeeded. The solution is genuinely new to us and we do not need Plato's theory of remembering to explain how we recognize it. I like the clear thinking and clean "stating" (state description? :) ! ---- ^^1^^ This is reflected in Kahlil Gibran's sentiments about learning, saying: >No man can reveal to you aught but that which already lies half asleep in the dawning of your knowledge. (from his poem [[On Teaching|http://www.katsandogz.com/onteaching.html]])
In his erudite style and book [[The Search for the Perfect Language|https://is.muni.cz/el/1421/podzim2017/LJMedB25/um/seminar_4/Eco_The_Search_for_the_Perfect_Language.pdf]], Umberto Eco describes work by the German mathematician [[Gottfried Wilhelm Leibniz|http://www.iep.utm.edu/leib-met/]] done around the year 1703, exploring universal languages.
Leibniz had exchanged ideas with the French Jesuit missionary [[Joachim Bouvet|https://en.wikipedia.org/wiki/Joachim_Bouvet]] (this is another case of "stumbling upon something big by mistake"^^1^^ :), which [[led him to define a binary number system|https://scholarworks.umt.edu/cgi/viewcontent.cgi?referer=&httpsredir=1&article=1315&context=tme]] (more than 100 years before [[George Boole|https://en.wikipedia.org/wiki/George_Boole]]!), by which he thought that "thoughtless generation of truths" could be achieved (sounds like programming a computer? :)
Being a [[Sinophile|https://en.wikipedia.org/wiki/Gottfried_Wilhelm_Leibniz#Sinophile]] and receiving an [[I Ching artifact|https://en.wikipedia.org/wiki/Gottfried_Wilhelm_Leibniz#/media/File:Diagram_of_I_Ching_hexagrams_owned_by_Gottfried_Wilhelm_Leibniz,_1701.jpg]] from Bouvert, Leibniz came up with binary encoding.
Here is Eco's description:
>Figure 14.1 shows the central structure of the diagrams seen by Leibniz. The sequence commences, in the upper left-hand corner, with six broken lines, then proceeds by gradually substituting unbroken for broken lines.
{{{
-- -- ----- -- -- ----- -- -- ----- -- -- -----
-- -- -- -- ----- ----- -- -- -- -- ----- -----
-- -- -- -- -- -- -- -- ----- ----- ----- -----
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- -- ----- -- -- ----- -- -- ----- -- -- -----
-- -- -- -- ----- ----- -- -- -- -- ----- -----
-- -- -- -- -- -- -- -- ----- ----- ----- -----
----- ----- ----- ----- ----- ----- ----- -----
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
Figure 14.1
}}}
>Leibniz read this sequence as a perfect representation of the progression of binary numbers (000, 001, 010, 110, 101, 011, 111 ... ). See figure 14.2.
{{{
-- -- ----- -- -- ----- -- -- ----- -- -- -----
-- -- -- -- ----- ----- -- -- -- -- ----- -----
-- -- -- -- -- -- -- -- ----- ----- ----- -----
0 1 0 1 0 1 0 1
0 0 1 1 0 0 1 1
0 0 0 0 1 1 1 1
0 1 10 11 100 101 110 111
0 1 2 3 4 5 6 7
Figure 14.2
}}}
>Once again, the inclination of Leibniz was to void the Chinese symbols of whatever meaning was assigned to them by previous interpretations, in order to consider their form and their combinational possibilities. Thus once more we find Leibniz on the track of a system of blind thought in which it was syntactic form alone that yielded truths. Those binary digits 1 and 0 are totally blind symbols which (through a syntactical manipulation) permit discoveries even before the strings into which they are formed are assigned meanings.
>
>In this way, Leibniz's thought not only anticipates by a century and a half Boole's mathematical logic, but also anticipates the true and native tongue spoken by a computer - not, that is, the language we speak to it when, working within its various programs, we type expressions out on the keyboard and read responses on the screen, but the machine language programmed into it. This is the language in which the computer can truly 'think' without 'knowing' what its own thoughts mean, receiving instructions and re-elaborating them in purely binary terms.
Eco emphasizes an important aspect of Leibniz's invention:
>[It] allowed Leibniz to invent a language of a radically different type, which - though remaining a priori - was no longer a practical, social instrument but rather a tool for logical calculation. In this sense, Leibniz's language, and the contemporary language of symbolic logic that descended from it, are scientific languages; yet, like all scientific languages, they are incapable of expressing the entire universe, expressing rather a set of //truths of reason//. Such languages do not qualify as a universal language because they fail to express those truths that all natural languages express - //truths off act//.
----
^^1^^ From Eco's book:
>When Leibniz described to Bouvet his own research in binary arithmetic, that is, his calculus by 1 and 0 (of which he also praised the metaphysical ability to represent even the relation between God and nothingness), Bouvet perceived that this arithmetic might admirably explain the structure of the Chinese hexagrams as well. He sent Leibniz in 1701 (though Leibniz only received the communication in 1703) a letter to which he added a wood-cut showing the disposition of the hexagrams. In fact, the disposition of the hexagrams in the wood-cut differs from that of the ''I Ching'', nevertheless, this error allowed Leibniz to perceive a signifying sequence which he later illustrated in his Explication de l'arithmetique binaire (1703).
from a lecture series by Martin Heidegger called “What is Called Thinking”: >Teaching is more difficult than learning. We know that; but we rarely think about it. And why is teaching more difficult than learning? Not because the teacher must have a larger store of information, and have it always ready. >Teaching is more difficult than learning because what teaching calls for is this: to let learn. The real teacher, in fact, lets nothing else be learned than — learning. > […] The teacher is far ahead of his apprentices in this alone, that he has still far more to learn than they—he has to learn to let them learn. The teacher must be capable of being more teachable than the apprentices. His conduct, therefore, often produces the impression that we properly learn nothing from him, if by “learning” we now suddenly understand merely the procurement of useful information. >The teacher is far less assured of his ground than those who learn are of theirs. If the relation between the teacher and the taught is genuine, therefore, there is never a place in it for the authority of the know-it-all or the authoritative sway of the official. It is still an exalted matter, then, to become a teacher—which is something else entirely than becoming a famous professor. From [[an article|https://researchspace.auckland.ac.nz/bitstream/handle/2292/22956/Teaching%20as%20letting%20learn%20What%20Martin%20Heidegger%20can%20tell%20us%20about%20one-to-ones.pdf?sequence=8]] by Sean Sturm: [img[teacher-students areas of overlap|./resources/Heidegger teaching 1.png][./resources/Heidegger teaching.png]]
From the book //Sailing Home// by the Zen teacher Norman Fischer: >Life as an arduous journey is an ancient metaphor. The Greek word //metapherein//, from which our English //metaphor// comes from, is made up of the words //meta//, meaning "over, or across", implying a change of state or location, and //pherein//, meaning "to bear, or carry". In modern as in ancient Greek, the word metapherein commonly means "to transport, or transfer". Though we think of a metaphor as a mere figure of speech, something poetic and decorative, in fact metaphors abound in our lives, underlying many concepts that we take for granted. And metaphors condition, far more than we realize, the way we think about ourselves and our world, and therefore the way we are and act. So to consider a metaphor seriously, bringing it to consciousness, turning it over in our minds and hearts, is to allow ourselves to be carried across toward some subtle yet profound inner change. > >Metaphors can engage our imagination and spirit, transporting us beyond the literality of what seems to be in front of us towards what's deeper, more lively, and dynamic. Objects in the world can be defined, measured and manipulated according to our specifications. But the heart can't be. It's requirements are more subtle, more vague. Metaphors are inexact and suggestive; they take an image or a concept and map it onto another image or concept that may seem quite disparate, as if to say "this is like that; understand this and you will understand that". In this way metaphor can help us to feel our way into the unspeakable, unchartable aspects of our lives. Seeing your life as a "spiritual odyssey" is a metaphorical truth. Contemplating your life as a spiritual odyssey can help you to enter hidden parts of your life. (see a more "analytic" treatment in [[On Metaphors and Mental Models - by Patrick O’Shaughnessy]]). ---- [[Douglas Hofstadter writes a lot about analogy|Douglas Hofstadter - The Man Who Would Teach Machines to Think]] being our (human) "engine of understanding". For example, from the [[excellent article about Hofstadter in the Atlantic Magazine|http://www.theatlantic.com/magazine/archive/2013/11/the-man-who-would-teach-machines-to-think/309529/]]: “At every moment,” Hofstadter writes in Surfaces and Essences, his latest book (written with Emmanuel Sander), “we are simultaneously faced with an indefinite number of overlapping and intermingling situations.” It is our job, as organisms that want to live, to make sense of that chaos. We do it by having the right concepts come to mind. This happens automatically, all the time. Analogy is Hofstadter’s go-to word. The thesis of his new book, which features a mélange of A’s on its cover, is that analogy is “the fuel and fire of thinking,” the bread and butter of our daily mental lives. “Look at your conversations,” he says. “You’ll see over and over again, to your surprise, that this is the process of analogy-making.” Someone says something, which reminds you of something else; you say something, which reminds the other person of something else—that’s a conversation. It couldn’t be more straightforward. But at each step, Hofstadter argues, there’s an analogy, a mental leap so stunningly complex that it’s a computational miracle: somehow your brain is able to strip any remark of the irrelevant surface details and extract its gist, its “skeletal essence,” and retrieve, from your own repertoire of ideas and experiences, the story or remark that best relates.
""" Life While-You-Wait. Performance without rehearsal. Body without alterations. Head without premeditation. I know nothing of the role I play. I only know it’s mine. I can’t exchange it. I have to guess on the spot just what this play’s all about. Ill-prepared for the privilege of living, I can barely keep up with the pace that the action demands. I improvise, although I loathe improvisation. I trip at every step over my own ignorance. I can’t conceal my hayseed manners. My instincts are for happy histrionics. Stage fright makes excuses for me, which humiliate me more. Extenuating circumstances strike me as cruel. Words and impulses you can’t take back, stars you’ll never get counted, your character like a raincoat you button on the run — the pitiful results of all this unexpectedness. If only I could just rehearse one Wednesday in advance, or repeat a single Thursday that has passed! But here comes Friday with a script I haven’t seen. Is it fair, I ask (my voice a little hoarse, since I couldn’t even clear my throat offstage). You’d be wrong to think that it’s just a slapdash quiz taken in makeshift accommodations. Oh no. I’m standing on the set and I see how strong it is. The props are surprisingly precise. The machine rotating the stage has been around even longer. The farthest galaxies have been turned on. Oh no, there’s no question, this must be the premiere. And whatever I do will become forever what I’ve done. """ ---- Zen Master Dogen expressed it succinctly: “It's too late to be ready.”
In an article in Aeon titled [["Virtues of uncertainty: Schools are in the business of forming character – so what kind of people will thrive in the 21st century?"|https://aeon.co/essays/a-life-of-tests-is-no-preparation-for-the-tests-of-life]], by Guy Claxton he lists the virtues that, he thinks, make people good at coping with uncertainty and complexity. >It is important that the virtues of uncertainty are broad enough to take beyond the school gates: that, surely, is the point of learning how to learn. Learning how to deal with the real uncertainties of modern life, and developing one’s own passionate interests and avocations. He caveats it, saying: This list is merely a provocation, an invitation to argue. 1. __''Curiosity''__ is the starting point. If you are not interested in things that are difficult or puzzling, you won’t engage. Curious people have an abiding sense of inquisitiveness. They wonder how things come to be, how they work, whether they might be otherwise. They live in a wonder-full world, not a world of dead certainties and cut-and-dried rules. They know how to ask good, pertinent, penetrating questions. They have a healthy scepticism about what they are told. 2. Young people surely need __''courage''__; not necessarily physical valour but the capacity to be up for a challenge, to be willing to take a risk and see what happens, not always playing it safe and sticking to things they know they can do. Courageous learners have the determination to stick with things that are hard, (although it is also a virtue to know when to quit, not because you are feeling stupid but because it really isn’t worth it). They bounce back from frustration; they don’t stay floored for long. 3. __''Exploration''__ is the active counterpart of curiosity. Inquisitive people enjoy the process of finding things out, of researching (whether it be footballers’ lives or particle physics). They like reading, but they also enjoy just looking at things, letting details and patterns emerge. They can let themselves get immersed in a book or a game; absorption in learning is often a pleasure. They can concentrate. They like sifting and evaluating ‘evidence’, not just reading or surfing the net uncritically, and their exploration usually breeds more questions. Explorers are also good at finding, making or capitalising on resources (tools, sources of information, people) that will support their investigations. 4. __''Experimentation''__ is the virtue of the practical inventor, actively trying things out to see if they work. Experimenters like tinkering, tuning and looking for small improvements. They don’t have to have a grand, ostensibly foolproof scheme before they try something out; they are at home with trial and error. They spend a good deal of time just playing with materials — paint, cogs, computer graphics — to see what they will do, uncovering new ‘affordances.’ They are happy practising, they enjoy drafting and redrafting, looking at what they’ve produced — a garden bed, an essay, a melody — and thinking about how they could build on and improve their own products and performances. 5. __''Imagination''__ is the virtue of fantasy, of using the inner world as a test-bed for ideas and as a theatre of possibilities. Good imaginers have the virtue of dreaminess: they know when and how to make use of reverie, how to let ideas come to them. They have a mixture of healthy respect and sceptical appraisal toward their own hunches and intuitions. They use mental rehearsal to develop their skills and readiness for tricky situations. They like finding links and making connections inside their own minds. They use imagery and metaphor in their thinking. 6. The creativity of imagination needs to be yoked to the virtue of __''discipline''__; of being able to think carefully, rigorously and methodically, as well as to take an imaginative leap. Reason isn’t the be-all and end-all of learning by any means, but the ability to follow a rigorous train of thought, and to spot the holes in someone else’s argument, as well as your own, is invaluable. Disciplined learners can create plans and forms of structure and organisation which support the painstaking ‘crafting’ of things that usually needs to follow the ‘brainwave.’ 7. The virtue of __''sociability''__, and of judiciously balancing sociability with solitariness, also seems essential. Effective learners know who to talk to (and who not), and when to talk (and when to keep silent) about their own learning. And they are good members of groups: they know how to listen, how to take turns, what kinds of contribution are helpful. They have the knack of being able to give their views and hold their own in debate, and at the same time stay open-minded to and respectful of others’ views: of giving feedback and suggestions skilfully and receiving them graciously. They are generous in sharing information, ideas and useful ways of thinking and exploring; and they are keen to pick up useful perspectives and strategies from others. 8. Finally there is the virtue of __''mindfulness''__, in the sense of being disposed to reflection and contemplation, taking time to mull things over, take stock and consider alternative strategies. Not paralysed by self-consciousness but capable of self-awareness, reflective learners can take a step back every so often and question their own priorities and assumptions. Thinking about your own thinking isn’t always useful (despite the current fad for ‘metacognition’) but it is needed at strategic moments. Mindfulness means giving yourself the time to go deeper, to see what conclusions you may have leapt to, and let a bigger picture emerge. And he makes the important point/distinction: >The thing is, virtues are not just skills, they are also habits or dispositions. Possessing the virtue of curiosity does not simply mean that you have the ability to ask good questions when someone prompts you. It means having a questioning frame of mind. The goal of character education cannot be merely to train skills. A skill is something you can do; not necessarily something that you are constitutionally disposed to do. A virtuous school has to be more than a ‘training’ institution; it has to be an incubator that develops and strengthens the desired qualities of mind through everything it does.
Type the text for 'Lisa Randall'
Lisp (standing for LISt Processing) is a computer programming language created by [[John McCarthy|http://en.wikipedia.org/wiki/John_McCarthy_%28computer_scientist%29]] in 1958, which quickly became one of the favored programming language for artificial intelligence (AI) research. Since I am interested in AI, I have always been drawn by Lisp, even though I'm very far from being a fluent Lisp programmer. But to quote (I ''love'' [[quotes|Quotes]]) [[Douglas Hofstadter]] from his wonderful //Metamagical Themas// book (written in 1985, pg. 396): Lisp is crisp. Or as Marilyn Monroe said in [the (1955) movie] //The ~Seven-Year Itch//: "I think it's jus-telegant!" By the way, me quoting Hofstadter quoting Marilyn Monroe is something that can turn into a series of regresses (quotes within quotes within quotes), which is something Lisp can handle very elegantly, as part of its abilities to deal with [[recursion]]. [[Someone|https://hackernoon.com/the-programming-language-im-looking-for-948d93f7a396]] comparing different programming languages allegorized: >“What sort of features do you have? What kind of programming language are you?”, asked the programmer. > >“Honey”, said Lisp, with a tinge of mischievous world-weariness to her voice, “I can be whatever you want.”
[[Alan Kay|https://en.wikipedia.org/wiki/Alan_Kay]] (a "[[CS Sage|https://en.wikipedia.org/wiki/List_of_computer_scientists]]"), at OOPSLA 1997, gave an [[insightful talk|https://www.youtube.com/watch?v=oKg1hTOQXoY]] titled "The computer revolution hasn't happened yet" ([[transcript|http://www.vpri.org/pdf/m2007007a_revolution.pdf]]), which highlights a few key ideas he thinks we have misunderstood/messed-up on the path to highly effective, efficient, scalable, and pervasive computing. The [[bullet-point highlights|http://www.cc.gatech.edu/fac/mark.guzdial/squeak/oopsla.html]] are captured by Mark Gudzial, with some comments by Kay. In the talk Kay shows half a page (pg. 13) from the LISP 1.5 Programmer's Manual (1985), and calls it the [["Maxwell Equations of Computer Science|http://en.wikipedia.org/wiki/Maxwell%27s_equations]]" [[A more detailed description and analysis|http://www.michaelnielsen.org/ddi/lisp-as-the-maxwells-equations-of-software/]]
In a review of [[David Denby's book 'Lit Up'|https://www.kirkusreviews.com/book-reviews/david-denby/lit-up/]], William Giraldi (in a chapter titled "Clearer Air" out of the book "American Audacity") writes: >Literature, I'm not sorry to say, isn’t a democracy. Literature is a tyranny -- a tyranny of the talented. >Here's the thesis driving Lit Up: >The liberal arts in general, and especially reading seriously, offer an opening to a wider life, the powers of active citizenship (including the willingness to vote); reading strengthens perception, judgment, and character; it creates understanding of other people and oneself, maybe kindliness and wit, and certainly the ability to endure solitude, both in the common sense of empty-room loneliness and the cosmic sense of empty-universe loneliness. Reading fiction carries you further into imagination and invention than you would be capable of on your own, takes you into other people's lives, and often, by reflection, deeper into your own.
The concept of logarithms is very powerful, because it reduces the level of complexity of calculations by one dimension. ([[Fourier Series|Fourier Series]] is another example of a powerful math concept) Instead of having to multiply or divide numbers (higher complexity/difficulty), it enables one to add or subtract (lower complexity/difficulty). And similarly, instead of raising to the power, or taking a root, one can multiple and divide, respectively. Here's an example I had created, demonstrating multiplying 2 numbers using addition of their logarithms. It's implemented as a [[Sage|http://www.sagemath.org/]] ''interactive animation'', vividly showing that addition of logarithms results in multiplication of the numbers (and similarly, that subtraction of logarithms is equivalent to division of the original numbers). [[The full User Interface for experimenting with multimplication and division using logarithms|./resources/Logarithm operations_Sage.html]] Or, a static image: !!The initial state shows two numbers to be multiplied, as arrows along both a linear and logarithmic ruler/scale: [img[Sage adding numbers using logarithms|./resources/sage_logarithms_2.png][./resources/sage_logarithms_2.png]]
I came across the following story Richard Feynman had told about his college days (at Cornell). I will somewhat modify it, to skip pieces which I think, reflect a somewhat condescending attitude toward, what Feynman calls, "the female mind", which was possibly due to his personal view (some claim he was somewhat sexist^^1^^), or a prevalent view in (American?) society at the time (the '60s). And I feel justified in doing this, because I think that the underlying implications about education and learning are really the important parts of the story (rather than Feynman's somewhat non-politically-correct asides (in this anecdote) and (more or less, depending on your tolerance level) offensive (occasional) behavior in other episodes^^2^^), and, as a relevant [[blog at Scientific American|https://blogs.scientificamerican.com/the-curious-wavefunction/richard-feynman-sexism-and-changing-perceptions-of-a-scientific-icon/]] mentions, Feynman was more complex than that.
Feynman was good at looking for, creating, and analyzing patterns, which he (and many others) thought are the essence of mathematics. As a student, he used to sit in the Cornell cafeteria and eat and try to overhear other students' conversations ("to see if there was one intelligent word coming out" - his words).
>I listened to a conversation between two girls, and one was explaining that if you want to make a straight line, you see, you go over a certain number to the right, for each row you go up, that is, if you go over each time the same amount when you go up a row, you make a straight line. A deep principle of analytic geometry! It went on. I was rather amazed.
>She went on and said, "suppose you have another line coming in from the other side and you want to figure out where they are going to intersect." Suppose on one line you go over two to the right for every one you go up, and the other line goes over three to the right for every one that it goes up, and they start twenty steps apart, etc. -- I was flabbergasted. She figured out where the intersection was!
>It turned out that one girl was explaining to the other how to knit argyle socks.
>I, therefore, did learn a lesson: [we are all] capable of understanding analytic geometry. [...] The difficulty may just be that we have [not] discovered a way to communicate [appropriately, and in the right context]. If it is done in the right way, you [will succeed in teaching/learning "difficult concepts"].
So, regarding learning and teaching, I think that this story echoes what Albert Einstein had said:
>Example isn’t another way to teach, it is the only way to teach.
Making things relevant is the strongest motivator to learning, and concrete examples are the foundation on which you (the learner //and// the teacher) can build abstractions.
Which echoes Seymour Papert's own personal [[story/experience about gears/gearboxes|http://www.papert.org/articles/GearsOfMyChildhood.html]] and multi-variable equations^^3^^, demonstrating/exemplifying (ha!) the power of [[constructionism|Constructionism, Constructivism, and learning tools implications]]!
----
^^1^^ from a blog post on the Scientific American site [[Richard Feynman, sexism and changing perceptions of a scientific icon|https://blogs.scientificamerican.com/the-curious-wavefunction/richard-feynman-sexism-and-changing-perceptions-of-a-scientific-icon/]]
>It's not surprising to find these anecdotes [described in the blog post] disturbing and even offensive, but I believe it would also be premature and simplistic to write off Richard Feynman as "sexist" across the board. People who want to accuse him of this seem to have inadvertently cherry-picked anecdotes.
^^2^^ as the physicist Janna Levin writes in her excellent book [[A Madman Dreams of Turing Machines|http://jannalevin.com/black-hole-blues-and-other-songs-from-outer-space/a-madman-dreams-of-turing-machines/]], about two other exceptional people, Kurt Gödel and Alan Turing:
> Their genius is a testament to our own worth, an antidote to insignificance; and their bounteous flaws are luckless but seemingly natural complements, as though greatness can be doled out only with an equal measure of weakness.
^^3^^ from Papert's article [[The Gears Of My Childhood|http://www.papert.org/articles/GearsOfMyChildhood.html]]:
>I believe that working with [gear] differentials did more for my mathematical development than anything I was taught in elementary school. Gears, serving as models, carried many otherwise abstract ideas into my head. I clearly remember two examples from school math. I saw multiplication tables as gears, and my first brush with equations in two variables (e.g., 3x + 4y = 10) immediately evoked the differential. By the time I had made a mental gear model of the relation between x and y, figuring how many teeth each gear needed, the equation had become a comfortable friend.
A Google Maps Street View car seen on the streets of Washington D.C. [img[GoogleMaps car|./resources/GoogleMapsCar.jpg]]
A recent article by Dan Neil, the car reviewer of the Wall Street Journal, in his column "Rumble Seat"^^1^^ titled [[Rolls-Royce Dawn Review: Charisma Comes Standard|http://www.wsj.com/articles/rolls-royce-dawn-review-charisma-comes-standard-1474581076]] reminded me of my father, who was a mechanical engineer by education (and used to manage a mechanics shop when he was young). My Dad loved cars and although he did not spend a lot of money on them, he took care of the cars he owned over the years, and kept up to date on the latest developments in the field throughout his life.
I remember the story Dad had told about Rolls Royce (a memory which the WSJ article had triggered), at the time when their famous [[Silver Shadow|https://en.wikipedia.org/wiki/Rolls-Royce_Silver_Shadow]] model came out, and they announced the specs of the legendary car. It listed usual details of length, width, weight, number of cylinders and their displacement, etc., but when it came to listing the //horsepower// of the engine (clearly an important fact!), they just wrote, in a typical British understatement: "Enough".
Anyway, Niel test-drove the car a few weeks before writing the article/review (or as he put it: "My turn at this automotive kissing booth came in August"), and noted that "with this car charisma comes standard" (the actual way he put it was: "a lot of parts -- engines and transmissions, bodies and body panels -- are sourced from Germany and BMW (which owns RR). But [[Goodwood|https://www.goodwood.com/]] is where they install the charisma.")
Neil's article, with his typical, somewhat dry but inventive humor and style, reminded me of my father's love for cars as well as his love of language and humor. Here are a few "linguistic pearls" from Neil's article:
* for a lot of people, an encounter with a ~Rolls-Royce is a tell-the-grandkids event, a touch of transcendence.
* The car accelerates to 60 mph in less than 5 seconds in the most untaxed manner
* this ~Rolls-Royce Dawn [the name of this model] moved around California like an MX missile during a Cold War exercise
* The author was definitely moved by the driving experience ("Imagine my face crying like Iron Eyes Cody." [an American actor playing Native American hero roles])
* The Dawn constitutes a sociological index on four 20-inch wheels ( Base price: $335,000. Price as tested: $400,000 - "a car worth more than the average house")
* it’s unforgettably large: a 17.3-foot convertible, with the geometric subtlety of a shipping container.
* The Dawn is a 2+2 convertible (drophead, in the parlance) and sibling to the fixed-head coupe Wraith. The Wraith is lighter and more powerful than the Dawn, but the latter owns the sky.
* The car engine is powerful (twin-turbo 6.6-liter V12 rated at 563 hp and a massive 575 pound-feet of torque at just 1,500 rpm): “whoosh” is too violent a word to describe how the Dawn gathers pace. With the superabundance of torque at any engine speed and the angels fluttering among the eight gears, the Dawn is ever ready, never hurried.
* From a standing start the Dawn can accelerate to 60 mph in under 5 seconds in a manner so unforced, so inevitable, as to take one off guard.
* the Dawn structure feels more like granite than steel. At least like the truck that delivers granite countertops.
* While the cruising is creamy to the n^^th^^, you wouldn’t say the Dawn’s driving character is sporty, exactly. It’s more like a high-speed longitudinal trust exercise.
* He concludes by writing: If drivers grip the thin-rim steering wheel lightly, and hold their breath just so, they can bend the mighty motorcar through a fine curve at truly entitled speeds. I never quite got there, but the car was waiting on his Lordship.
----
^^1^^ [[A rumble seat|https://en.wikipedia.org/wiki/Rumble_seat]] (American English), dicky seat, dickie seat or dickey seat (British English), also called mother-in-law seat, is an upholstered exterior seat which folded into the rear of a coach, carriage, or early automobile. Depending on its configuration, it provided exposed seating for one or two passengers.
When I introduce the Exploratory Computer Science (CS) course I teach in high school, I say that the programming languages we will be learning (Scratch from MIT or Snap! from UC Berkeley) are "Low Floor, High Ceiling" languages, which means that very quickly the students can program reasonably functional and useful programs and see appealing and engaging results (so that's the "Low Floor" aspect). And, that (maybe despite appearances) these languages are not "kiddie languages" and students can end up programming pretty sophisticated and complex programs with these languages and go pretty far implementing complex CS concepts (so that's the "High Ceiling" part). Usually, the students don't pay too much attention to this, and the parents I tell it to when describing the course, very often have a puzzled expression on their face, so let me tell you about a recent event which illustrates the point. In the second week into the school year (so that's low floor for you :), the students are able to program a reasonable computer game in terms of action and effects (sound, animation, etc.) But, one student came to me and said: you know, Mr. Mark, this game is somewhat boring. And I thought to myself "uh-oh, what happened?", but commented that the student seemed to be quite engaged a minute ago, playing the game on the computer. To which the student responds: Actually, the game is not bad (you see, high schoolers can't show too much enthusiasm; they have to stay cool :), but, I want to know what my score is, and without knowing it, it's not much fun. I had to seize the moment, so I told him that I can explain to him how to add a score to his game, if he'd like. And proceeded to explained about variables and changes to values of variables, and so on. The student paid very close attention, smiled at the end, and said "OK, I got it!", and "thank you!" and went on to implement scoring in his game. I, too, smiled, and thought to myself: when was the last time a teacher taught a student about variables, change of value, and so on, an got a smile and a thank you!?
[[Welcome]] [[Education]] [[Computational Thinking/Literacy]] [[Mathematics]] [[Books]] [[Quotes]] [[About me]] [[ToDo]] [[GettingStarted]]
Make it right before you make it fast. Make it clear before you make it faster. Keep it right when you make it faster. P. J. Plauger - Kernighan and Plauger, The Elements of Programming Style
Making connections between things, concepts, knowledge domains (as well as people, but that's for another tiddler) is creative, makes you wiser, deepens your understanding and/or skills, and is a source of joy and beauty overall.
Sometimes making connections involves breaking (or at least, penetrating) walls/lines/barriers and going against established forms, (mis)conceptions, norms, and "common knowledge" ("wisdom").
But as Halford John Mackinder had said "[[Knowledge is one. Its division into subjects is a concession to human weakness.]]"
The truth is that these divisions are human-made. They may be useful, but they are context-dependent and reflect a human perspective (or state of knowledge), not a law of nature. And as such, and under different circumstances or a different context, may not be useful, and therefore probably worth reconsidering and/or changing and/or abandoning in favor of different ones (and so it goes...).
This brings to mind the beautiful poem ''Psalm'' by [[Nobel Laureate|Wislawa Szymborska's Nobel Prize lecture (1996)]] [[Wislawa Szymborska|https://en.wikipedia.org/wiki/Wis%C5%82awa_Szymborska]] (translated by Stanislaw Baranczak and Clare Cavanagh). It's sharp, observant, and mischievous:
>Oh, the leaky boundaries of man-made states!
>How many clouds float past them with impunity;
>how much desert sand shifts from one land to another;
>how many mountain pebbles tumble onto foreign soil
>in provocative hops!
>
>Need I mention every single bird that flies in the face of frontiers
>or alights on the roadblock at the border?
>A humble robin - still, its tail resides abroad
>while its beak stays home. If that weren't enough, it won't stop bobbing!
>
>Among innumerable insects, I'll single out only the ant
>between the border guard's left and right boots
>blithely ignoring the questions "Where from?" and "Where to?"
>
>Oh, to register in detail, at a glance, the chaos
>prevailing on every continent!
>Isn't that a privet on the far bank
>smuggling its hundred-thousandth leaf across the river?
>
>And who but the octopus, with impudent long arms,
>would disrupt the sacred bounds of territorial waters?
>And how can we talk of order overall?
>when the very placement of the stars
>leaves us doubting just what shines for whom?
>
>Not to speak of the fog's reprehensible drifting!
>And dust blowing all over the steppes
>as if they hadn't been partitioned!
>And the voices coasting on obliging airwaves,
>that conspiratorial squeaking, those indecipherable mutters!
>
>Only what is human can truly be foreign.
>The rest is mixed vegetation, subversive moles, and wind.
Therefore, I think that developing the habit and the skill of looking for and making new connections is very important. It opens you up, makes you wiser, and more skillful at living (and working). And, the good news is that it can be learned/developed.
In a [[conversation between Krista Tippett and David Whyte On Becoming Wise|https://www.youtube.com/watch?v=Nup6deehcck]] (1:40 hrs.), he said:
>You can actually practice shaping a mind which is constantly enlarging the context, and becoming more generous, and more in contact with the frontier which is the unknown.
>You can do that through asking "beautiful questions" and through genuine conversations.
to which she agreed and added:
>Questions are a mighty form of words.
This is also echoed in [[John O’Donohue's take on questions as lanterns|John O’Donohue - questions]], [[David Whyte's sentiments|David Whyte - questions]] expressed elsewhere, too.
Alan Kay (a "[[CS Sage|https://en.wikipedia.org/wiki/List_of_computer_scientists]]") promotes computing as an excellent means (environment, tool, context) for developing connections (and knowledge, insight, etc.) and enables asking (and trying, and simulating) these "beautiful questions", when he states that [[The Real Computer Revolution Has Not Happened Yet]]. And that's why I am so drawn to Computing, and am so passionate about it.
Man is the best computer we can put aboard a spacecraft ... and the only one that can be mass produced with unskilled labor.
Man's mind, once stretched by a new idea, never regains its original dimensions.
[[Peter Drucker|https://www.drucker.institute/perspective/about-peter-drucker/]] [[wrote how to perform well|http://sbuweb.tcu.edu/jmathis/Org_Mgmt_Materials/Managing_Oneself.pdf]] (also on [[GD|https://drive.google.com/open?id=1Grk0H4fkwwNI9b21LRnEljGuLWeOTF5E]]) and identified several factors and principles impacting professional self development, performance, and success: * It is critical to find out what ones strengths are and be both realistic and critical about it. * once one knows what ones strengths are, one should work on developing and improving those strengths, and, counter to 'established wisdom', not work on improving ones weaknesses, since as Drucker writes: > It takes far more energy and work to improve from incompetence to mediocrity than it takes to improve from first-rate performance to excellence. And yet most people -- especially most teachers and most organizations-concentrate on making incompetent performers into mediocre ones. Energy,resources, and time should go instead to making a competent person into a star performer. * A few ''personality traits'' usually determine how a person performs: ** Am I a reader or a listener? ** How do I learn? *** by writing? by speaking? ** Do I work well with people, or am I a loner? ** And if you do work well with people, you then must ask: in what relationship? *** as a subordinate or leader? as a team player or alone? as a coach or mentor? ** Do I produce results as a decision maker or as an adviser? ** Do I perform well under stress, or do I need a highly structured and predictable environment? ** Do I work best in a big organization or a small one? * The conclusion bears repeating: Do not try to change yourself -- you are unlikely to succeed. But work hard to improve the way you perform. And try not to take on work you cannot perform or will only perform poorly. * What are my ''values''? ** This is not a question of ethics. With respect to ethics, the rules are the same for everybody. ** A person's strengths and the way that person performs rarely conflict; the two are complementary. But there is sometimes a conflict between a person's values and his or her strengths. What one does well -- even very well and successfully -- may not fit with one's value system. In that case, the work may not appear to be worth devoting one's life to (or even a substantial portion thereof). * Where do I ''belong''? ** Successful careers are not planned.They develop when people are prepared for opportunities because they know their strengths, their method of work, and their values. Knowing where one belongs can transform an ordinary person -- hardworking and competent but otherwise mediocre -- into an outstanding performer. * What should my ''contribution'' be? ** What does the situation require? ** Given my strengths, my way of performing, and my values, how can I make the greatest contribution to what needs to be done? ** And finally, what results have to be achieved to make a difference? ** The question in most cases should be: Where and how can I achieve results that will make a difference within the next year and a half? *** The answer must balance several things. **** First, the results should be hard to achieve -- they should require "stretching," to use the current buzzword. But also, they should be within reach. To aim at results that cannot be achieved -- or that can be only under the most unlikely circumstances -- is not being ambitious; it is being foolish. **** Second, the results should be meaningful.They should make a difference. **** Finally,results should be visible and, if at all possible, measurable. *** From this will come a course of action: what to do, where and how to start, and what goals and deadlines to set. * Responsibility for ''Relationships'' ** Very few people work by themselves and achieve results by themselves - a few great artists, a few great scientists,a few great athletes. Most people work with others and are effective with other people. That is true whether they are members of an organization or independently employed. Managing yourself requires taking responsibility for relationships. *** The first is to accept the fact that other people are as much individuals as you yourself are. They perversely insist on behaving like human beings. This means that they too have their strengths; they too have their ways of getting things done; they too have their values. *** To be effective, therefore, you have to know the strengths, the performance modes, and the values of your coworkers. **** The first secret of effectiveness is to understand the people you work with and depend on so that you can make use of their strengths, their ways of working, and their values. Working relationships are as much based on the people as they are on the work. *** The second part of relationship responsibility is taking responsibility for communication. **** Even people who understand the importance of taking responsibility for relationships often do not communicate sufficiently with their associates. They are afraid of being thought presumptuous or inquisitive or stupid. They are wrong. **** knowledge workers should request this of everyone with whom they work, whether as subordinate, superior, colleague, or team member. * __''The Second Half of Your Life''__ ** There are three ways to develop a second career. The first is actually to start one. Often this takes nothing more than moving from one kind of organization to another. ** The second way to prepare for the second half of your life is to develop a parallel career. ** Finally, there are the social entrepreneurs. They keep doing what they have been doing, but also start something new (e.g., non-profit work) ** There is one prerequisite for managing the second half of your life: You must begin long before you enter it. ** It is vitally important for the individual, and equally for the individual's family, to have an area in which he or she can contribute, make a difference, and be somebody. That means finding a second area -- whether in a second career, a parallel career, or a social venture -- that offers an opportunity for being a leader, for being respected, for being a success.
Type the text for 'Marilynne Robinson'
In a short but insight-rich [[|https://computinged.wordpress.com/2015/05/13/how-to-teach-computer-science-with-media-computation/]]blog post, Mark Guzdial from Georgia Tech brings up a list of excellent tips for how to teach his [[Media Computation class|http://coweb.cc.gatech.edu/mediaComp-teach]]. I currently have a segment in my Principles of CS class which uses audio/music (EarSketch from Georgia Tech) to teach/reinforce basic concepts like loops and functions, but I have not incorporated image processing into this course yet. I'm still working on seeing how image processing works with Trinket, which is what I'm using for this course. Anyway, Guzdial's recommendations and my comments/thoughts on them: * Let the students be creative. ** I totally agree: They should have the opportunity to "pour their interests and personality" into their work/projects. * Let the students share what they produce. ** What I found: Most of them enjoy doing it and it motivates them as they work on their projects. It also introduces a different pace and atmosphere into the class. * Code live in front of the class. ** I should do that much more often. The challenge I see is students' attention span and how to keep them engaged. But I think that Guzdial's points are valid: When the teacher makes a mistake and fixes it, the students see (a) that errors are expected and (b) there is a process for fixing them. * Pair programming leads to better learning and retention. ** I had tried this and still need to figure out how to make sure both students are equally engaged and learning from this. * [[Peer instruction|http://www.peerinstruction4cs.org/]] is great. Not only does peer instruction lead to better learning and retention outcomes, but it also gives the teacher better feedback on what the students are learning and what they are struggling with. We strongly encourage the use of peer instruction in computing classes. ** I haven't tried this and need to find out more about this technique. Looks like a [[PI website|http://www.peerinstruction4cs.org/]] has some good reasons for doing it. ** [[on the site|https://blog.peerinstruction.net/2014/05/01/what-is-peer-instruction-in-2-mins/]] Julie Schell lists linked supplemental readings: flipped classrooms , pre-class assignments, ConcepTests, Peer Instruction Workflow, Voting Sequences, Displaying Results, Grouping Students for Productive Conversations, and Classroom Response Systems. * Worked examples help with learning creativity. ** This is a big and important one, and seems to have a body of research supporting its pedagogic effectiveness on learning and transfer.
From the [[Information Philosopher's Encyclopedia|http://www.informationphilosopher.com/solutions/philosophers/twain/#IV]]. Twain, personified by the Old Man (or, O.M.) in the dialog below, is conversing (in a Socratic dialog) with a Younger Man (or, Y.M.) about Truth and ~Truth-Seekers (and, by clear implication, human nature): >O.M.: We are always hearing of people who are around SEEKING AFTER TRUTH. I have never seen a (permanent) specimen. I think he had never lived. But I have seen several entirely sincere people who THOUGHT they were (permanent) Seekers after Truth. They sought diligently, persistently, carefully, cautiously, profoundly, with perfect honesty and nicely adjusted judgment -- until they believed that without doubt or question they had found the Truth. THAT WAS THE END OF THE SEARCH. The man spent the rest of his life hunting up shingles wherewith to protect his Truth from the weather. If he was seeking after political Truth he found it in one or another of the hundred political gospels which govern men in the earth; if he was seeking after the Only True Religion he found it in one or another of the three thousand that are on the market. In any case, when he found the Truth HE SOUGHT NO FURTHER; but from that day forth, with his soldering-iron in one hand and his bludgeon in the other he tinkered its leaks and reasoned with objectors. There have been innumerable Temporary Seekers of Truth -- have you ever heard of a permanent one? In the very nature of man such a person is impossible. And Twain's brilliant, self-reflecting pivot: >O.M.: I have been a humble, earnest, and sincere ~Truth-Seeker. >Y.M.: Very well? >O.M.: The humble, earnest, and sincere ~Truth-Seeker is always convertible by such means [i.e., able arguments backed by collated facts and instances]. >Y.M.: I am thankful to God to hear you say this, for now I know that your conversion -- >O.M.: Wait. You misunderstand. I said I have BEEN a ~Truth-Seeker. >Y.M.: Well? >O.M.: I am not that now. Have you forgotten? I told you that there are none but temporary ~Truth-Seekers; that a permanent one is a human impossibility; that as soon as the Seeker finds what he is thoroughly convinced is the Truth, he seeks no further, but gives the rest of his days to hunting junk to patch it and caulk it and prop it with, and make it weather-proof and keep it from caving in on him. Hence the Presbyterian remains a Presbyterian, the Mohammedan a Mohammedan, the Spiritualist a Spiritualist, the Democrat a Democrat, the Republican a Republican, the Monarchist a Monarchist; and if a humble, earnest, and sincere Seeker after Truth should find it in the proposition that the moon is made of green cheese nothing could ever budge him from that position; for he is nothing but an automatic machine, and must obey the laws of his construction. >Y.M.: After so -- >O.M.: Having found the Truth; perceiving that beyond question man has but one moving impulse -- the contenting of his own spirit-- and is merely a machine and entitled to no personal merit for anything he does, it is not humanly possible for me to seek further. The rest of my days will be spent in patching and painting and puttying and caulking my priceless possession and in looking the other way when an imploring argument or a damaging fact approaches. In one sense or interpretation of Twain's words, he has a very dark, even depressing, view of human nature (a "machine" seeking truth, then latching on to whatever it is, and endlessly patching it, defending it, blind and resistant to any change and/or new information). But, knowing Twain's style a bit, and understanding what humor, tongue-in-cheek, and irony can achieve in terms of making someone re-examine their stance and possibly changing (or at least being open to evolving) it, I think that Twain made here a brilliant move. I (choose to) interpret this as him holding up a mirror to us, and saying: look, there is a danger here, and this is how ugly and hopeless it can get, unless we are aware of the consequences, and decide to change our attitude.
In his interesting book //Would-be Worlds - How Simulation is Changing the Frontiers of Science//, John L. Casti is actually showing in numerous ways how Computing is changing multiple fundamental assumptions we have had about different aspects of life and knowledge in general, and math and science in particular.
One specific example is how in 1976 the 2 mathematicians Kenneth Appel and Wolfgang Haken proved the "Four Color Map" problem. As Georges Gonthier in his [[description of the way he went about proving it|http://www.ams.org/journals/notices/200811/tx081101382p.pdf]] puts it simply:
The four color map problem states that
>the regions of any simple planar map can be colored with only four colors, in such a way that any two adjacent regions have different colors. [This] can on the one hand be understood even by schoolchildren as “four colors suffice to color any flat map” and on the other hand be given a faithful, precise mathematical interpretation using only basic notions in topology.
The Four Color Map problem stood unsolved since Francis Guthrie expressed it as an "innocent little coloring puzzle" in 1852 ^^1^^. As Casti put it, Appel and Haken startled the mathematical world not just because they were able to finally prove that four colors were indeed sufficient to color any map, but, probably more importantly, because they were able to prove this using a supercomputer.
Up to that point in time, a math proof had been understood as the application of a procedure, logic, and deduction, which could be __performed and verified by a human__. Thomas Tymoczko (a philosopher of mathematics) called this (considered essential?) characteristic of a math proof "(human) surveyability".
In Tymoczko's view ("The ~Four-Color Problem and its Mathematical Significance", 1980), the ~Appel-Hacken proof failed this "surveyability" criterion by, he argued, substituting experiment for deduction:
> […] if we accept the [~Four-Color Theorem] as a theorem, we are committed to changing the sense of "theorem", or, more to the point, […] the sense of the underlying concept of "proof".
> [… the] use of computers in mathematics, as in the [~Four-Color Theorem], introduces empirical experiments into mathematics.
> Whether or not we choose to regard the [~Four-Color Theorem] as proved, we must admit that the current proof is no traditional proof, no a priori deduction of a statement from premises. It is a traditional proof with a […] gap, which is filled by the results of a well-thought-out experiment.
Appel and Haken's procedure employed a Computational procedure which ran through a large (1,936) but finite (!) set of topological (map) configurations to show that, indeed, 4 colors were sufficient. For the first time in the history of math proofs, a procedure which could not be done and/or verified by hand, had been used - employing a supercomputer, running calculations for many hours.
To make things even murkier, the computer technology used was known to have a computation error rate of 1 error per thousand hours of computation.
Since then, the Four Color theorem has been checked and verified as well as (re)proven using similar but somewhat different computation approaches, and has been found to be solid ^^2^^. Nevertheless, there are still math "purists" who have doubts whether this Computational approach is an "honest-to-god" mathematical proof, and are concerned that if this is acceptable, "it will turn math (based on deduction) into physics (based on experimentation)".
But (and probably because Computing is near and dear to me :), I share [[Julie Rehmeyer's view|https://www.sciencenews.org/article/how-really-trust-mathematical-proof]] that:
> [Our belief is that] The one source of truth is mathematics. Every statement is a pure logical deduction from foundational axioms, resulting in absolute certainty.
> [...] Well … in theory. The reality, though, is that mathematicians make mistakes. And as mathematics has advanced, some proofs have gotten immensely long and complex, often drawing on expertise from far-flung areas of math. Errors can easily creep in.
> [...] Where humans falter, computers can sometimes prevail. A group of mathematicians and computer scientists believe that with new proof-validation programs, the dream of a fully spelled-out, rigorous mathematics, with every deduction explicit and correct, can be realized.
> [...] Before long, they say, ordinary mathematicians will be using these tools as part of their everyday work.
[[Simon Yuill|http://www.lipparosa.org/]], in a chapter titled //Bend Sinister: Monstrosity and Normative Effect in Computational Practice// (in the book [[Fun and Software - Exploring Pleasure Paradox and Pain in Computing|https://monoskop.org/images/1/14/Goriunova_Olga_ed_Fun_and_Software_Exploring_Pleasure_Paradox_and_Pain_in_Computing.pdf]] edited by Goriunova Olga), mentions Appel and Haken again:
> many mathematicians [distrust] computer-demonstrated proofs, such as evidenced, famously, in the lukewarm response to Appel and Haken’s proof for the Four Colour Theorem (1976). The theorem seeks to determine whether or not all the countries on a map can be coloured in using only four distinct colours and ensuring that no two neighbouring countries are coloured the same. This was the first major theorem to be proven using software assistance having eluded purely human analysis since it was originally conjectured in 1852, yet its solution was not celebrated.
>The negative response of the mathematics community is epitomized in the words of one critic, Ian Stewart, who argued that this approach did not explain //why// the proof was correct:
>>This is partly because the proof is so long that it is hard to grasp (including the computer calculations, impossible!), but mostly because it is so apparently structureless. The answer appears as a kind of monstrous coincidence. Why is there an unavoidable set of reducible configurations? The best answer at the present time is: there just is. The proof: here it is, see for yourself. The mathematician’s search for hidden structure, his pattern-binding urge, is frustrated.
>The ~Appel-Haken proof confounded the aesthetics of mathematicians for the set of 1,482 different map configurations required to verify it could not be grasped by human imagination. It was not succinct. It was not elegant. In combining human and mechanical means it transgressed the prohibition against crossing between different disciplines such as that between arithmetic and geometry, the metabasis ex allo genos [i.e., crossing from one genus (or domain) to another in the course of a proof (for example, switching to use algebra in a geometry proof)], as established in Aristotle’s Posterior Analytics [Aristotle's Theory of Knowledge and Demonstration]. The proof exuded an excess of computational materiality, it had contagion, it could not be given human shape.
As you can probably guess, I am not willing (at this point, with what I know/feel today) to so strictly separate between domains and "keep walls up" (or preserve walls, which are there for historic/evolutionary reasons) between knowledge disciplines.
To echo Halford John Mackinder who said "[[Knowledge is one. Its division into subjects is a concession to human weakness.]]", we should strive to acquire knowledge and gain insights using every capability/device/tool we have at our disposal, and not just for practical reasons (i.e., "do whatever it takes to accomplish the task of learning/knowing more"), but also for aesthetic reasons. Using multiple devices to get at some truth (or at least new knowledge) is in my view, exposing the interconnectedness of things/domains, and has therefore the potential to "harmonize" and bring us closer to more deeply understand the world/reality.
Having said that, I can definitely understand Simon Yuill's (and Ian Stewart's) sentiment of "displeasure" with the method of proof; it may have been "more elegant" and aesthetically pleasing to proof the Four Colour Theorem without the use of "brute-force computing". But on the other hand, the use of computing paves new (interdisciplinary)paths and opens up new windows between and across domains, and it seems to me that there is nothing bad about it :)
It's also interesting to read what two great mathematicians, Stanislaw Ulam and Mark Kac, had to say about [[using computers in math|Ways of "doing math"]], in an interview with Mitchell Feigenbaum.
----
^^1^^ - From Georges Gonthier in his [[paper|http://www.ams.org/journals/notices/200811/tx081101382p.pdf]]: [Guthrie] managed to embarrass successively his mathematician brother, his brother’s professor, Augustus de Morgan, and all of de Morgan’s visitors, who couldn’t solve it; the Royal Society, who only realized ten years later that Alfred Kempe’s 1879 solution was wrong; and the three following generations of mathematicians who couldn’t fix it.
^^2^^ - see for example:
* Gonthier, Georges (2008), "[[Formal Proof - The Four-Color Theorem|http://www.ams.org/journals/notices/200811/tx081101382p.pdf]]" and
* Robertson, Neil; Sanders, Daniel P.; Seymour, Paul; Thomas, Robin (1997), "[[The Four-Colour Theorem|http://ac.els-cdn.com/S0095895697917500/1-s2.0-S0095895697917500-main.pdf?_tid=839a41cc-ab28-11e5-924e-00000aab0f01&acdnat=1451062800_6e3ae15df2c2b4516aacd58eaf7048b8]]"
From Ian Stewart's (as the Brits say:) //lovely// book //Professor Stewart's Hoard of Mathematical Treasures//: *Proof by Contradiction: ‘This theorem contradicts a well-known result due to Isaac Newton.’ *Proof by Metacontradiction: ‘We prove that a proof exists. To do so, assume that there is no proof … ‘ *Proof by Deferral: ‘We’ll prove this next week.’ *Proof by Cyclic Deferral: ‘As we proved last week …’ *Proof by Indefinite Deferral: ‘As I said last week, we’ll prove this next week.’ *Proof by Intimidation: ‘As any fool can see, the proof is obviously trivial.’ *Proof by Handwaving: ‘Self-explanatory.’ (Most effective in seminars and conference talks.) *Proof by Vigorous Handwaving: More tiring, but more effective. *Proof by Over-optimistic Citation: ‘As Pythagoras proved, two cubes never add up to a cube.’ *Proof by Personal Conviction: ‘It is my profound belief that the quaternionic pseudo-Mandelbrot set is locally disconnected.’ *Proof by Lack of Imagination: ‘I can’t think of any reason why it’s false, so it must be true.’ *Proof by Forward Reference: ‘My proof that the quaternionic pseudo-Mandelbrot set is locally disconnected will appear in a forthcoming paper.’ (Often not as forthcoming as it seemed when the reference was made.) *Proof by Example: ‘We prove the case n = 2 and then let 2 = n.’ *Proof by Outsourcing: ‘Details are left to the reader.’ *Statement by Outsourcing: ‘Formulation of the correct theorem is left to the reader.’ *Proof by Unreadable Notation: ‘If you work through the next 500 pages of incredibly dense formulas in six alphabets, you’ll see why it has to be true.’ *Proof by Authority: ‘I saw Milnor in the cafeteria and he said he thought it’s probably locally disconnected.’ *Proof by Vague Authority: ‘The quaternionic pseudo-Mandelbrot set is well known to be locally disconnected.’ *Proof by Provocative Wager: ‘If the quaternionic pseudo-Mandelbrot set is not locally disconnected, I’ll jump off London Bridge wearing a gorilla suit.’ *Proof by Reduction to the Wrong Problem: ‘To see that the quaternionic pseudo-Mandelbrot set is locally disconnected, we reduce it to Pythagoras’s Theorem.’ Second Thoughts *‘This is a one-line proof – if we start sufficiently far to the left.’
> Master a second language, preferably math. : -- from [[Rules for my unborn son|http://rulesformyunbornson.tumblr.com/]] <<list-links "[tag[math-item]]">> """ """ <html> <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-nc-sa/3.0/us/88x31.png" /></a><br />This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/">Creative Commons Attribution-NonCommercial-ShareAlike 3.0 United States License</a>. </html>
A common question math students ask when studying matrices (notations, operations, etc.): what is it good for? When/how can this be ''really'' used? In response, I had created an animated demonstration/example, showing how matrix operations can be used in (movie) animation to magnify and rotate images, objects, scenes. It's implemented as a [[Sage|http://www.sagemath.org/]] ''interactive animation'', vividly showing that multiplying the coordinates of various bodies/images/outlines/wire-frames (expressed as vectors or matrices), by "rotation matrices" or "magnification matrices" results in interesting animations. [[The full User Interface for experimenting with magnifying and rotating points and objects|./resources/Matrix operations_Sage.html]] Or a static image: [img[Sage rotating and magnifying objects using matrices|./resources/sage_matrix_operations_2.png][./resources/sage_matrix_operations_2.png]]
""" One of those many dates that no longer ring a bell. Where I was going that day, what I was doing -- I don't know. Whom I met, what we talked about, I can't recall. If a crime had been committed nearby, I wouldn't have had an alibi. The sun flared and died beyond my horizons. The earth rotated un-noted in my notebooks. I'd rather think that I'd temporarily died than that I kept on living and can't remember a thing. I wasn't a ghost, after all. I breathed, I ate, I walked. My steps were audible, my fingers surely left their prints on doorknobs. Mirrors caught my reflection. I wore something or other in such-and-such a color. Somebody must have seen me. Maybe I found something that day that had been lost. Maybe I lost something that turned up late. I was filled with feelings and sensations. Now all that's like a line of dots in parentheses. Where was I hiding out, where did I bury myself? Not a bad trick to vanish before my own eyes. I shake my memory. Maybe something in its branches that has been asleep for years will start up with a flutter. No. Clearly I'm asking too much. Nothing less than one whole second. """ ---- poem by Wislawa Szymborska^^1^^, translated by Stanislaw Baranczak and Clare Cavanagh ^^1^^ see [[Wislawa Szymborska's Nobel Prize lecture (1996)]]
Measuring programming progress by lines of code is like measuring aircraft building progress by weight. But I think that since aircraft building progress //may// be reasonably measured by the rate of weight-addition, as it is built __according to plan__ (!), I would paraphrase it to: >Measuring program and programmer effectiveness by lines of code is like measuring aircraft effectiveness by weight. Or as seen on the [[Agile Insights blog|https://medium.com/agile-insights/if-you-cant-count-what-s-important-you-make-what-you-can-count-important-62f8171abc1e]]: >If you can’t count what’s important you make what you can count important.
The following original quote is attributed to Bill Gates: >Measuring programming progress by lines of code is like measuring aircraft building progress by weight. But I think that since aircraft building progress //may// be reasonably measured by the rate of weight-addition, as it is built __according to plan__ (!), I would paraphrase it to: >Measuring program and programmer effectiveness by lines of code is like measuring aircraft effectiveness by weight. Or as seen on the [[Agile Insights blog|https://medium.com/agile-insights/if-you-cant-count-what-s-important-you-make-what-you-can-count-important-62f8171abc1e]]: >If you can’t count what’s important you make what you can count important. The following [[story|https://www.folklore.org/StoryView.py?project=Macintosh&story=Negative_2000_Lines_Of_Code.txt&sortOrder=Sort+by+Date&topic=Software+Design]] from the "good old days" (1980's) of Apple (and the [[Lisa computer|https://www.mac-history.net/apple-history-2/apple-lisa/2007-10-12/apple-lisa]] development) nicely illustrates the frequent tension between the desire of "Management" to measure things, and the need for common sense and measuring "the right thing" (since it is well-known in project management that "you get the behavior you measure"). >In early 1982, the Lisa software team was trying to buckle down for the big push to ship the software within the next six months. Some of the managers decided that it would be a good idea to track the progress of each individual engineer in terms of the amount of code that they wrote from week to week. They devised a form that each engineer was required to submit every Friday, which included a field for the number of lines of code that were written that week. > >[[Bill Atkinson|https://en.wikipedia.org/wiki/Bill_Atkinson]], the author of Quickdraw and the main user interface designer, who was by far the most important Lisa implementor, thought that lines of code was a silly measure of software productivity. He thought his goal was to write as small and fast a program as possible, and that the lines of code metric only encouraged writing sloppy, bloated, broken code. > >He recently was working on optimizing Quickdraw's region calculation machinery, and had completely rewritten the region engine using a simpler, more general algorithm which, after some tweaking, made region operations almost six times faster. As a by-product, the rewrite also saved around 2,000 lines of code. > >He was just putting the finishing touches on the optimization when it was time to fill out the management form for the first time. When he got to the lines of code part, he thought about it for a second, and then wrote in the number: -2000 [minus two thousand!]. > >I'm not sure how the managers reacted to that, but I do know that after a couple more weeks, they stopped asking Bill to fill out the form, and he gladly complied. And as you can imagine, [[I am in total agreement|The most secure, the fastest, and the most maintainable code (by far :) is the code not written.]] with Atkinson :) Another take and good example on this is from [[an article titled"tao of programming"|https://fare.livejournal.com/tag/tao%20of%20programming]] by ~François-René Rideau: >Measurement is no substitute for judgment >There's worse than having a long feedback loop: you could be using information to actively make adjustments that shape your company in counter-productive ways. For instance, you could be measuring the number of issues resolved by each team member, and rewarding employees based on that, leading to employees introducing more bugs, splitting every bug into plenty of independently registered issues and sub-issues, and spending half their time on the issue-tracking system rather than on the actual issues. Or you could reward developers based on lines of code, leading to unmaintainable code bloat. Measuring things is very important to detect anomalies that need to be addressed, but it is important not to use measurements in a way that will skew incentives, or you'll fall victim of Goodhart's law. Also, whatever effort you expand on measuring things that don't matter, or doing anything that doesn't matter, is effort you don't expand doing things that do matter.
Men occasionally stumble over the truth, but most of them pick themselves up and hurry off as if nothing had happened.
I recently finished reading a short Sci-Fi story by Stephen Baxter called [[Turing's Apples|http://kasmana.people.cofc.edu/MATHFICT/mfview.php?callnumber=mf934]], in which he has an interesting spin on a familiar theme of communication (sending and/or receiving) efforts with aliens, along the lines of [[SETI|https://en.wikipedia.org/wiki/Search_for_extraterrestrial_intelligence]]. In the Baxter's story, we on Earth, receive a message form aliens, and are trying to decipher it. This reminds me of our effort to "send a message out", in the form of the [[golden record|https://voyager.jpl.nasa.gov/golden-record/golden-record-cover/]] put on the Voyager spaceship, containing [[music, images, sounds, and greetings|https://voyager.jpl.nasa.gov/golden-record/whats-on-the-record/]], to be carried by the spacecraft out of the solar system. It's interesting to compare Baxter's idea of an "effective message" which he imagined aliens sending out in the story, with the message we had sent out aboard Voyager in 1977. Here's how Baxter describes the investigation of two scientists/mathematicians (brothers) working on the message from the aliens (called Eaglets, on account of the message source from the [[Eagle Nebula|http://earthsky.org/clusters-nebulae-galaxies/the-awesome-beauty-of-m16-the-eagle-nebula]]): >And it was Wilson's intuition that these things were bits of executable code: programs you could run. Even as expressed in the Eaglets' Odd flowing language, he thought he recognised logical loops, start and stop statements. Mathematics may or may not be universal, but computing seems to be - my brother had found Turing machines, buried deep in an alien database. > >Wilson translated the segments into a human mathematical programming language, and set them to run on a dedicated processor. They turned out to be like viruses. Once downloaded on almost any computer substrate they organised themselves, investigated their environment, started to multiply, and quickly grew, accessing the data banks that had been downloaded from the stars with them. Then they started asking questions of the operators: simple yes-no, true-false exchanges that soon built up a common language. > >"The Eaglets didn't send us a message," Wilson had whispered to me on the phone in the small hours; at the height of it he worked twenty-four seven. "They downloaded an AI [Artificial Intelligence]. And now the AI is learning to speak to us." > >It was a way to resolve a ferocious communications challenge. The Eaglets were sending their message to the whole Galaxy; they knew nothing about the intelligence, cultural development, or even the physical form of their audiences. So they sent an all-purpose artificial mind embedded in the information stream itself, able to learn and start a local dialogue with the receivers. > >This above all else proved to me how Smart the Eaglets must be. It didn't comfort me at all that some commentators pointed out that this "Hoyle strategy" had been anticipated by some human thinkers; it's one thing to anticipate, another to build. I wondered if those viruses found it a challenge to dumb down their message for creatures capable of only ninth-order Shannon entropy^^1^^, as we were. And here is how Maria Popova at [[BrainPickings|https://www.brainpickings.org/]] is [[describing the effort by Carl Sagan and others to get a message on board of the Voyager|https://www.brainpickings.org/2014/02/10/murmurs-of-earth-sagan-golden-record/]]: >[it's fascination to see] how, in the early fall of 1977, he [Sagan] and a team of collaborators imbued a [time capsule with great] hopefulness of cosmic proportions and sent it into space aboard the Voyager spacecraft as humanity’s symbolic embrace of other civilizations. On it, they set out to explain our planet and our civilization to another in 117 pictures, greetings in 54 different languages and one from humpback whales, and a representative selection of “the sounds of Earth,” ranging from an avalanche to an elephant’s trumpet to a kiss, as well as nearly 90 minutes of some of the world’s greatest music. So the alien message imagined by Baxter is obviously much more sophisticated compared to the Carl Sagan's idea and Voyager's Golden Record. It is much more versatile and universal, but also much more //dangerous//^^2^^. The aliens basically had sent a [["Universal Computer" (AKA a "Universal Turing Machine")|https://en.wikipedia.org/wiki/Universal_Turing_machine]], which in principle is capable of computing/programming/executing "anything" (with [[limitations|https://link.springer.com/chapter/10.1007/978-0-85729-535-4_7]]! Talk about a [[letting the genie out of the bottle|https://dictionary.cambridge.org/us/dictionary/english/let-the-genie-out-of-the-bottle]]! ---- ^^1^^ - from [[Peter Russell's article|http://www.peterrussell.com/Dolphin/DolphinLang.php]] //Look who's talking//: >The higher entropy levels, second order and up, relate to the notion of "conditional probabilities": once you have seen a particular sequence of elements, what are your chances of predicting the next element in the series? If, for instance, you know the first and second words of a phrase, the third-order entropy tells you (in logarithmic form) the odds of guessing the third word correctly. Analyses of English and Russian suggest that these languages show evidence of 8th or 9th-order Shannon entropy, meaning that when presented with a string of eight words, you have some ability (slim but non-zero) to predict what the ninth word might be. After that, though, all bets are off. If you want to guess what the 10th word is, the previous nine are of no value. ^^2^^ - this may explain why [[Arthur C. Clarke|https://en.wikiquote.org/wiki/Arthur_C._Clarke]] wanted to [[add to the message to extraterrestrials|https://science.nasa.gov/science-news/science-at-nasa/2011/28apr_voyager2]] the sentence: >Please leave me^^3^^ alone; let me^^3^^ go on to the stars. ^^3^^ - on second thought, it's not clear who "me" refers to: the human race (begging the aliens), or the Voyager spaceship begging humans (who potentially could at [[some time in the future overtake the 1977 spaceship|https://science.nasa.gov/science-news/science-at-nasa/2011/28apr_voyager2]])
Metamagical Themas, Questing for the Essence of Mind and Pattern, by Douglas Hofstadter, Basic Books, 1985
<<forEachTiddler
where
'tiddler.tags.contains("book-chapter") && tiddler.tags.contains("Metamagical Themas")'
sortBy
'tiddler.title'>>
In the wonderful book [[The issue at hand|The issue at hand]] by Gil Fronsdal, he writes about mindfulness: At the heart of insight meditation is the practice of mindfulness, the cultivation of clear, stable and nonjudgmental awareness. While mindfulness practice can be highly effective in helping bring calm and clarity to the pressures of daily life, it is also a spiritual path that gradually dissolves the barriers to the full development of our wisdom, compassion and freedom. Cultivating our capacity to see clearly is the foundation for learning how to be present for things as they are, as they arise. It is learning to see without the filters of bias, judgment, projection,or emotional reactions. It also entails developing the trust and inner strength that allow us to be with things as they are instead of how we wish they could be. Mindfulness relies on an important characteristic of awareness: awareness by itself does not judge, resist, or cling to anything. Meditation can and does improve mindfulness (among other beneficial results :) . But as [[Sharon Salzberg|https://www.sharonsalzberg.com/about/]] [[had said|https://onbeing.org/blog/the-fractal-moment-an-invitation-to-begin-again/7589/]]: >In actuality, meditation is simple, but not easy: you rest your attention on something like the breath in order to stay present, and, as thoughts carry you away, you begin again an incalculable number of times. That is why meditation is a practice. It is this practice of training one’s attention that makes meditation so powerful. >[...] >There is joy and an important sense of renewal in each effort to begin again. In this way, meditation is not about the creation of a singular experience but about changing our relationship to experience. ---- Compare and Contrast: A wonderful [[poem by Wislawa Szymborska|MAY 16, 1973 by Wislawa Szymborska]] about how difficult it is to be mindful (and the "naturalness" of living mindlessly)
In Edgar Allan Poe's "detective story" [["The Purloined Letter"|On "The Purloined Letter" by Edgar Allan Poe]] Dupin (one of the main characters) tells the following story, to illustrate how oblivious we sometimes (often?) are to things in plain sight, or how assumptions (sometimes, unconscious) blind us to the real nature of things, or what's right in front of us: >“There is a game of puzzles,” he [Dupin] resumed, “which is played upon a map. One party playing requires another to find a given word—the name of town, river, state or empire—any word, in short, upon the motley and perplexed surface of the chart. A novice in the game generally seeks to embarrass his opponents by giving them the most minutely lettered names; but the adept selects such words as stretch, in large characters, from one end of the chart to the other. These, like the over-largely lettered signs and placards of the street, escape observation by dint of being excessively obvious; and here the physical oversight is precisely analogous with the moral inapprehension by which the intellect suffers to pass unnoticed those considerations which are too obtrusively and too palpably self-evident. Which reminds me of a similar point David Foster Wallace made at the [[commencement speech at Kenyon College (for the graduating class of 2005)|http://bulletin-archive.kenyon.edu/x4280.html]]. >There are these two young fish swimming along and they happen to meet an older fish swimming the other way, who nods at them and says "Morning, boys. How's the water?" >And the two young fish swim on for a bit, and then eventually one of them looks over at the other and goes "What the hell is water?"^^1^^ And Foster Wallace clarifies: >I am not the wise old fish. The point of the fish story is merely that the most obvious, important realities are often the ones that are hardest to see and talk about. Stated as an English sentence, of course, this is just a banal platitude, but the fact is that in the day to day trenches of adult existence, banal platitudes can have a life or death importance, or so I wish to suggest to you on this dry and lovely morning. He proceeds by describing the dangers (and falling into the trap) of some sort of [[concept bubble (or "echo chamber")|The Scientific Bubble]] through another story: >There are these two guys sitting together in a bar in the remote Alaskan wilderness. One of the guys is religious, the other is an atheist, and the two are arguing about the existence of God with that special intensity that comes after about the fourth beer. And the atheist says: "Look, it's not like I don't have actual reasons for not believing in God. It's not like I haven't ever experimented with the whole God and prayer thing. Just last month I got caught away from the camp in that terrible blizzard, and I was totally lost and I couldn't see a thing, and it was 50 below, and so I tried it: I fell to my knees in the snow and cried out 'Oh, God, if there is a God, I'm lost in this blizzard, and I'm gonna die if you don't help me.'" And now, in the bar, the religious guy looks at the atheist all puzzled. "Well then you must believe now," he says, "After all, here you are, alive." The atheist just rolls his eyes. "No, man, all that was was a couple Eskimos happened to come wandering by and showed me the way back to camp." > >It's easy to run this story through kind of a standard liberal arts analysis: the exact same experience can mean two totally different things to two different people, given those people's two different belief templates and two different ways of constructing meaning from experience. Because we prize tolerance and diversity of belief, nowhere in our liberal arts analysis do we want to claim that one guy's interpretation is true and the other guy's is false or bad. Which is fine, except we also never end up talking about just where these individual templates and beliefs come from. Meaning, where they come from INSIDE the two guys. As if a person's most basic orientation toward the world, and the meaning of his experience were somehow just hard-wired, like height or shoe-size; or automatically absorbed from the culture, like language. As if how we construct meaning were not actually a matter of personal, intentional choice. Plus, there's the whole matter of arrogance. The nonreligious guy is so totally certain in his dismissal of the possibility that the passing Eskimos had anything to do with his prayer for help. True, there are plenty of religious people who seem arrogant and certain of their own interpretations, too. They're probably even more repulsive than atheists, at least to most of us. But religious dogmatists' problem is exactly the same as the story's unbeliever: blind certainty, a close-mindedness that amounts to an imprisonment so total that the prisoner doesn't even know he's locked up. ---- ^^1^^ this story about awareness of your environment/context/life, reminds me of what Susan Moon wrote in her book [["This is getting old"|https://www.lionsroar.com/this-is-getting-old-september-2010/]] (in the chapter titled "This Vast Life"): >I like to think about how we are completely held by the atmosphere in a literal way. The air that surrounds each of our bodies, that flows in and out of our lungs, is not nothing. It's thick with molecules, and it fills up all the gaps and cracks between us and the other bodies and objects around us: the furniture, the walls of the room, the trees outside, the buildings. There's no empty space. The air is fluid, making room for us, so that each of us inhabits a nook that is exactly our size and shape. The air kindly moves with us when we move. > >[...] >We are all connected, molecule to molecule. I'm held by everything that's not me.
""" The commonplace miracle: that so many common miracles take place. The usual miracles: invisible dogs barking in the dead of night. One of many miracles: a small and airy cloud is able to upstage the massive moon. Several miracles in one: an alder is reflected in the water and is reversed from left to right and grows from crown to root and never hits bottom though the water isn't deep. A run-of-the-mill miracle: winds mild to moderate turning gusty in storms. A miracle in the first place: cows will be cows. Next but not least: just this cherry orchard from just this cherry pit. A miracle minus top hat and tails: fluttering white doves. A miracle (what else can you call it): the sun rose today at three fourteen a.m. and will set tonight at one past eight. A miracle that's lost on us: the hand actually has fewer than six fingers but still it's got more than four. A miracle, just take a look around: the inescapable earth. An extra miracle, extra and ordinary: the unthinkable can be thought. """ ---- Poem by Wislawa Szymborska^^1^^, translated by Joanna Trzeciak ^^1^^ see [[Wislawa Szymborska's Nobel Prize lecture (1996)]]
In his excellent book "The Darker the Night, the Brighter the Stars" Paul Broks writes: >IN GREEK MYTHOLOGY the Moon, Selene, fell in love with a beautiful shepherd, Endymion, as her beams fell on his sleeping face. Dreading the prospect that, like all mortals, he would age and die, she got Zeus to grant him eternal youth, which he did. But also eternal sleep. > >AT 02:56 COORDINATED Universal Time on 21 July 1969, Neil Armstrong becomes the first human being to set foot on the surface of the Moon. He has prepared [[a few words to mark the occasion|https://www.ndtv.com/world-news/is-neil-armstrongs-famous-moon-landing-quote-really-a-misquote-524458]]^^1^^: “That's one small step for (a) man, one giant leap for mankind.” The “a” is in parenthesis because, although it is required for the sentence to make any sense at all, it was not uttered by the astronaut—or, at least, it was not heard by the millions of earthlings tuned in for the Moon landing. > >Armstrong later claimed to have voiced the “a” and that, somehow, the crucial little word was lost in transmission. We'll never know. Who cares? > >Aldrin descended the lunar module ladder for his Moonwalk about twenty minutes later. I wonder if thoughts of his mother crossed his mind on his lunar stroll. She had killed herself the previous year in a state of depression triggered, apparently, by the prospect of her son's forthcoming Moon mission and the fame and the acclaim it would be bound to bring. She feared she wouldn't cope. Her maiden name Moon. > >THOSE FIRST FOOTFALLS in the moon dust punctured a embrane—the thin, porous film that separates reality and imagination. Some saw this as an act of destruction, a violation. It was a sentiment that inspired Tom Stoppard to write //Jumpers//, a play about philosophy, murder and Moon landings. He was curious to know whether, “if and when men landed on the Moon, something interesting would occur in the human psyche.” He cites a statement from the Union of Persian Storytellers (“if you can imagine such a thing”) to the effect that a Moon landing would be damaging to the livelihood of the storytellers. > >The Moon as romantic metaphor, as symbol of love and dreams, of the unconscious mind, the passage of time, of life and death, would be diminished. The veil would drop and the Moon would be revealed as rock and dust. We knew that anyway, but there are different ways of knowing. > >Then it happened. Armstrong and Aldrin walked on the Moon and nothing changed. [[Carl Sagan also tells a story of another myth about a celestial object|A keen eye (but not what you think)]], which also reflects (ha!) on human nature. (see also [[The Last Words Spoken on the Moon]]) ---- ^^1^^ - see [[GD local copy|https://docs.google.com/document/d/1PAsseF0KS2ka3L6CbT3b6krwXcY3688JAJRy5RkAPHA/edit?usp=sharing]]
Ever since I had read [ext[Richard Hamming's "The Unreasonable Effectiveness of Mathematics"|resources/Hamming.html]], where he "[[normalizes our thinking|Perhaps there are thoughts we cannot think]]" about "unthinkable thoughts" (basically asking why we (erroneously) think it should not be possible that they exist), I have been looking for some simple example of what I thought (ha!) was such a "rarefied creature". [[Haldane|https://en.wikipedia.org/wiki/J._B._S._Haldane]] once said: [[My own suspicion is that the universe is not only queerer than we suppose, but queerer than we can suppose... I suspect that there are more things in heaven and earth that are dreamed of, or can be dreamed of, in any philosophy.]] I have just finished an interesting book //The Accidental Universe - The World You Thought You Knew// by Alan Lightman, where he writes about how we, humans, are getting more and more used to (or even (and sadly? or at least, I suspect, unavoidably?)) "comfortable" living in what he calls "The Disembodied Universe". Lightman points out that both modern physics and biology (and, like Bret Victor, [[I have to add|Enabling to think the unthinkable]], technology and computers!) have uncovered an invisible universe: >Since Foucault, more and more of what we know about the universe is undetected and undetectable by our bodies. What we see with our eyes, what we hear with our ears, what we feel with our fingertips, is only a tiny sliver of reality. Little by little, using artificial devices, we have uncovered a hidden reality. It is often a reality that violates common sense. It is often a reality that is strange to our bodies. It is a reality that forces us to reexamine our most basic concepts of how the world works. And it is a reality that discounts the present moment and our immediate experience of the world. He gives some examples from physics, like experiencing the Earth's turning through Foucault's Pendulum, the discovery of electro-magnetic waves and the formulation of their behavior^^1^^ by James Clerk Maxwell, experimenting with radio waves by Heinrich Hertz, the confirmation of time dilation predicted and calculated by Albert Einstein, and so on. He quotes a friend of Einstein, Niels Bohr, who wrote about the fact that "the world of the quantum [quantum physics] is so foreign to our sensory perceptions that we don't even have words to describe it." >we find ourselves here on the very path taken by Einstein of adapting our modes of perception borrowed from the sensations to the gradually deepening knowledge of the laws of nature. The hindrances met on this path originate above all in the fact that ... every word in the language refers to our ordinary perceptions. Lightman [[laments the impact of science and technology on our worldview|On losing our personal relationship with the world around us]] and the creation of this "invisible", "disembodied" universe: >It is an irony to me that the same science and technology that have brought us closer to nature by revealing these invisible worlds have also separated us from nature and from ourselves. Much of our contact with the world today is not an immediate, direct experience, but is instead mediated by various artificial devices such as television, cell phones, iPads, chat rooms, and mind-altering drugs. So back to my attempt to find simple examples of unthinkable thoughts. This is a simple, almost "everyday example" in our high tech world today, which could truly be considered unthinkable let's say 200 years ago (or maybe before the Wright brothers' first airplane flight on December 17, 1903). This example was triggered in my mind by Lightman's book, but also by the fact that this week my son is in Israel on a business trip. In light of these coincidences, I thought of the fact that my son had to take a 10 hour flight to Frankfurt, Germany, followed by another 4 hour flight to Israel, and that if I want to talk to him, I need to remember that there is a 10 hour time difference between the US West Coast and Israel due to timezone differences. Now, isn't this a (nowadays mundane) example of a thought (and a "universe of concepts and knowledge") which had been "unthinkable" a mere 200 years ago? And it comes so naturally to us. And it doesn't seem like an "impossible feat" or thought. Which reminds me of the scene from //Through the ~Looking-Glass// by Lewis Carroll (Charles Lutwidge Dodgson), when Alice meets the White Queen (Chapter 5: Wool and Water): >[the Queen says:] "I'm just one hundred and one, five months and a day." >"I can't believe that!" said Alice. >"Can't you?" the Queen said in a pitying tone. "Try again: draw a long breath, and shut your eyes." >Alice laughed. "There's no use trying," she said: "one can't believe impossible things." >"I daresay you haven't had much practice," said the Queen. "When I was your age, I always did it for half-an-hour a day. Why, sometimes I've believed as many as six impossible things before breakfast." So here you have it^^2^^. As the White Queen says: it's possible (to think/calculate time zones, //and// there is an algorithm for doing it :) It seems to me that thinking always involves words, and if you attempt to think the unthinkable, you need to //invent// new words or at least create new meanings to existing words. I think that this is echoed by [[Ursula K. Le Guin|http://www.ursulakleguin.com/UKL_info.html]] who had said (ha!): >Words are events, they do things, change things. They transform both speaker and hearer; they feed energy back and forth and amplify it. They feed understanding or emotion back and forth and amplify it. Maria Popova of [[BrainPickings|https://www.brainpickings.org/]] [[covers UKL's book|https://www.brainpickings.org/2015/10/21/telling-is-listening-ursula-k-le-guin-communication/]] called // The Wave in the Mind: Talks and Essays on the Writer, the Reader, and the Imagination//, in which she (Popova) writes (words again :): >Every act of communication is an act of tremendous courage in which we give ourselves over to two parallel possibilities: the possibility of planting into another mind a seed sprouted in ours and watching it blossom into a breathtaking flower of mutual understanding; and the possibility of being wholly misunderstood, reduced to a withering weed. And who should know better than UKL about [[creating new worlds|http://www.ursulakleguin.com/PlausibilityinFantasy.html]] full of unthinkable thoughts and realities :) On the website of a new [[documentary film|http://worldsofukl.com/]] about her work, UKL is quoted (last words (for this post) :): >As great scientists have said and as all children know, it is above all by the imagination that we achieve perception, and compassion, and hope. ---- ^^1^^ - see on the [[beauty of the definition of the programming language Lisp|LISP as the Maxwell Equations of Computer Science]] as the equivalent of Maxwell's equations. ^^2^^ - I found a discussion of "unthinkable thoughts" or in this case "unthinkable questions", which at one point become thinkable/askable in the book [[The Meaning of Life|https://ia601202.us.archive.org/21/items/MeaningOfLife-VeryShortIntroduction-TerryEagleton/MeaningOfLifeAVeryShortIntroductionTheTerryEagleton2008OxfordUniversityPressIsbn9780199532179.pdf]] by [[Terry Eagleton|http://www.lancaster.ac.uk/english-literature-and-creative-writing/about-us/staff/terry-eagleton]] where he writes: >We constantly push the frontier forward by acquiring and validating new knowledge and experiences, which expand the "questioning horizon": >Not any question is possible at any given time. Rembrandt could not ask whether photography had rendered realist painting redundant.
This is meant to follow on [[the email/letter sent to students|A few words of encouragement (and advice :)]] who had taken the Exploring CS course, after they have taken a second CS course ("Fundamentals of CS").
It is inspired by a panel discussion described in the appendix of [[Donald Knuth]]'s book //Things a Computer Scientist Rarely Talks About//. The panelists included Donald Knuth, Guy Steele, Mitch Kapor, and a couple of others.
The study of computer science, as we know it, is a human activity, so far. It involves creativity and purpose, and such can be called "spiritual", at least in part.
Speaking of purpose begs the question of //why// should you do computer science?
Is it because it's fun? Because it's beautiful? To earn enough money to do what you want? To earn enough to support a family? To buy all the ice cream you want? To improve the lot of human kind? To advance human knowledge and perspective on life, reality, the universe, and everything? :)
Computer science is an interesting combination of science, math, and art. It involves both specific content and specific methods. The content in this field has no intrinsic purpose or intention. It's just the what and the how of doing CS. The question of Why, deals with the purpose.
Computer science studies processes, description of processes (programs), description of description of processes (programming languages), description of description of description processes (theory of semantics), and so on.
Analogies to human social structures such as committees, bus and bank queues sometimes help us to design data structures and algorithms. Attempts to model human intellectual behavior on a computer have also let to important insights. So it's possible that the study of human purpose, inspiration, values, and spirituality, may lead us in a similar way to important advances and insights in computer science. And we will use metaphors rooted in these areas to help us deal with ever greater complexity.
As we study computational processes of ever greater complexity, we find ourselves drawn ever more to describe processes as having purposes: at first, purposes inherited from their human creators, but perhaps later purposes of their own. And then we must face the question of whether this use of language is merely a metaphor, or in some deep sense, the truth.
And so, what we can make from computing (on its own) and with computing (and other domains), and using it as a tool and method to help us understand ourselves and reality better, to give us some insights, to extend ourselves, and to "augment our being", we will definitely engage computing in a spiritual way for spiritual purposes.
"""
"""
(see also [[A few words of encouragement (and advice :)]]).
(see also [[Attitude Matters Too (in programming as in life)]]).
My own suspicion is that the universe is not only queerer than we suppose, but queerer than we can suppose... I suspect that there are more things in heaven and earth that are dreamed of, or can be dreamed of, in any philosophy. Echoing and expanding on William Shakespeare's Hamlet saying: >there are more things in heaven and earth, Horatio, than are dreamt of in your philosophy.
<<forEachTiddler
where
'tiddler.tags.contains("book-chapter") && tiddler.tags.contains("Natural-Born Cyborgs: Minds, Technologies, and the Future of Human Intelligence")'
sortBy
'tiddler.title'>>
In the WSJ column [[20 odd questions|https://www.wsj.com/news/types/20-odd-questions]] Neil deGrasse Tyson was [[asked|https://www.wsj.com/articles/neil-degrasse-tyson-1495122652]], among other things: >''We instill in children the misconception that'': science is memorizing the names of things. That’s an aspect of it, but it’s not the core. The core is understanding objects. Get that into your 6-year-old, and you’ve got nothing more to teach them. I beg to differ; I think that he doubly (!) missed the boat: __First__, I think that deGrasse Tyson tilts it too much towards understanding //objects//. I think that understanding processes is not less (if not more) important. It's //not// just Western vs. Easter philosophy differences/emphases. It's about the importance and criticality of relationships between objects and the processes that impact them. As [[Alan Kay once said about Alan Perlis|Alan Kay on "Rethinking Computer Science Education"]]: >We need to establish "real computer science" >>- Alan Perlis meant that we need a "science of processes" - a science to study processes and things in process >>- processes in mechanics, biology, society, politics, chemistry, tech/engineering, mental etc. __Second__, I think that at the core (to borrow deGrasse Tyson's term) of science (and any other worthwhile human endeavor) is the sense of wonder; this is really the engine for creativity, discovery, knowledge, and understanding. And that if you "get that into your 6-year-old, [...] you’ve got nothing more to teach them" ! [[Albert Einstein had said it|https://sciphilos.info/docs_pages/docs_Einstein_fulltext_css.html]] better than me: >"The most beautiful thing we can experience is the mysterious. It is the source of all true art and science. He to whom the emotion is a stranger, who can no longer pause to wonder and stand wrapped in awe, is as good as dead —his eyes are closed." BTW, and to be fair, Einstein also said about understanding, awe and wonder: >Compound interest is the eighth wonder of the world. He who understands it, earns it ... he who doesn't ... pays it. ;)
A different (but related) perspective on [[forms of literacy|Computing Literacy]] is given by [[Robert Logan|http://www.physics.utoronto.ca/people/homepages/logan/]] in his book //The Sixth Language: Learning a Living in the Internet Age// ([[see article (on GD)|https://drive.google.com/open?id=1onMD8ckPHZMTQuSRSZWXm9AVwY4pfR51]]).
The six languages he considers are: speech, writing, mathematics, science, computers and the Internet, forming an evolutionary chain in human development.
Since Logan had worked with Marshall ~McLuhan, it's not surprising to me that he's using the terms "languages", since both men were "very big" on communication, media, messages, and so on (you surely remember ~McLuhan's "the medium is the message"). I think that "literacies" may be a more suitable (and also less bombastic ;-) term, but Logan definitely has good insights.
In a [[good review|http://www.cjc-online.ca/index.php/journal/article/view/1265/1273]] of the book by Paul Heyer in the Canadian Journal of Communication, Heyer brings up some very good points about it.
In reference to education, the 5th and sixth languages (computers and the Internet) are (to my point earlier) treated as literacies:
>Computers have created an information revolution, and the Internet now enmeshes us in a knowledge archive of global proportions. The ability to navigate comfortably this terrain is essential and should be part and parcel of even a back-to-basics educational curriculum.
On the natural (and predictable) evolution of new languages (again, I think media, or literacies are better terms, but, this is Logan's choice):
>One ~McLuhan notion that is given pronounced emphasis is how the content of a new medium is usually that of the medium that preceded it. The first printed books, for example, in subject matter and form, replicated the earlier manuscripts; early television cannibalized radio (some radio shows were even simulcast for the newer medium); and as Logan observes, early computers sourced print, mathematics, and science.
This echoes [[Seymour Papert's insight/principle|An Exploration in the Space of Mathematics Educations]] for education pedagogy and material ("New media open the door to new contents").
And then:
>After this initial conservative phase, the new medium eventually establishes unique formats, often unanticipated during its inception, and the world is forever changed.
As an aside, it's interesting that he points out a parallelism in evolutionary biology:
>Romer's rule [...] states that an evolutionary adaptation is usually conservative in that it tends to help an organism maintain its existing lifeway in the face of changing environmental circumstances rather than immediately enabling it to exploit fully a new niche. When lungfishes emerged during the Devonian period, for example, the new adaptation did not initially establish the terrestrial mode, although it eventually would. Instead, it allowed organisms to get from one diminishing body of water to another, thereby helping them maintain the status quo.
In the review article, Heyer points out Logan's enthusiasm about computers and the Internet, that
>Few would argue against a high-tech component to education. But such insistence needs to be tempered. There is a cost, along with //the// cost.
and provides one example, where providing schools with computers and connecting them to the Internet, does not automatically/naturally enhance education and learning, and the cost of doing that, may come at the expense of other means (like more and better teachers), which may impact education/learning much more.
About television (and by extension, any "passive video media"):
>The book also seems to dismiss television as an educational tool because of its alleged non-interactivity. Yet ~McLuhan, who advocated the use of multimedia in education, had more to say regarding it than any other medium save print.
>The 500-channel universe offers a plethora of documentary and dramatic material students are unlikely to view on their own, but which they could be assigned to watch, assess, and deconstruct in an interactive classroom context as they are taught aspects of media literacy, visual communication, and textual analysis-at a minimal cost. In seeing television as inherently passive and an enemy of education, Logan overlooks a more indictable and truancy-producing culprit, which is, ironically, intimately tied to the computer -- the video game.
(Logan's book [[What is Information?|What is Information? by Robert Logan]] is also applicable to information, knowledge, learning, and technology)
In the book titled "Nine Algorithms That Changed the Future", John ~MacCormick covers a few (nine? I'm not sure I'd cover just these and not others, but this is a pretty good list :) great ones. As a Computer Science curriculum developer and teacher, I have to say that this is also a good list of suggestions for Computer Science teaching projects :) The numbers at the beginning of the following paragraphs are the chapter numbers in the book. 1 Introduction: What Are the Extraordinary Ideas Computers Use Every Day? How were the great ideas of computer science born? Hereʼs a selection: In the 1930s, before the first digital computer has even been built, a British genius founds the field of computer science, then goes on to prove that certain problems cannot be solved by any computer to be built in the future, no matter how fast, powerful, or cleverly designed. In 1948, a scientist working at a telephone company publishes a paper that founds the field of information theory. His work will allow computers to transmit a message with perfect accuracy even when most of the data is corrupted... 2 Search Engine Indexing: Finding Needles in the World’s Biggest Haystack Search engines have a profound effect on our lives. Most of us issue search queries many times a day, yet we rarely stop to wonder just how this remarkable tool can possibly work. The vast amount of information available and the speed and quality of the results have come to seem so normal that we actually get frustrated if a question can’t be answered within a few seconds. We tend to forget that every successful web search extracts a needle from the world’s largest haystack: the World Wide Web. 3 ~PageRank: The Technology That Launched Google Architecturally speaking, the garage is typically a humble entity. But in Silicon Valley, garages have a special entrepreneurial significance: many of the great Silicon Valley technology companies were born, or at least incubated, in a garage. This is not a trend that began in the dot-com boom of the 1990s. Over 50 years earlier—in 1939, with the world economy still reeling from the Great Depression—~Hewlett-Packard got underway in Dave Hewlett’s garage in Palo Alto, California. Several decades after that, in 1976, Steve Jobs and Steve Wozniak operated out of Jobs’ garage in Los Altos, California, after founding their... 4 Public Key Cryptography: Sending Secrets on a Postcard Humans love to gossip, and they love secrets. And since the goal of cryptography is to communicate secrets, we are all natural cryptographers. But humans can communicate secretly more easily than computers. If you want to tell a secret to your friend, you can just whisper in your friend’s ear. It’s not so easy for computers to do that. There’s no way for one computer to “whisper” a credit card number to another computer. If the computers are connected by the internet, they have no control over where that credit card number goes, and which other computers get to find... 5 ~Error-Correcting Codes: Mistakes That Fix Themselves These days, we’re used to accessing computers whenever we need them. Richard Hamming, a researcher working at the Bell Telephone Company labs in the 1940s, was not so lucky: the company computer he needed was used by other departments and available to him only on weekends. You can imagine his frustration, therefore, at the crashes that kept recurring due to the computer’s errors in reading its own data. Here is what Hamming himself had to say on the matter: Two weekends in a row I came in and found that all my stuff had been dumped and nothing was done.... 6 Pattern Recognition: Learning from Experience In each previous chapter, we’ve looked at an area in which the ability of computers far outstrips the ability of humans. For example, a computer can typically encrypt or decrypt a large file within a second or two, whereas it would take a human many years to perform the same computations by hand. For an even more extreme example, imagine how long it would take a human to manually compute the ~PageRank of billions of web pages according to the algorithm described in chapter 3. This task is so vast that, in practice, it is impossible for a human. Yet... 7 Data Compression: Something for Nothing We’re all familiar with the idea of compressing physical objects: when you try to fit a lot of clothes into a small suitcase, you can squash the clothes so that they are small enough to fit even though they would overflow the suitcase at their normal size. You have compressed the clothes. Later, you can decompress the clothes after they come out of a suitcase and (hopefully) wear them again in their original size and shape. Remarkably, it’s possible to do exactly the same thing with information: computer files and other kinds of data can often be compressed to a... 8 Databases: The Quest for Consistency Consider the following arcane ritual. A person takes from a desk a specially printed pad of paper (known as a checkbook), writes some numbers on it, and adds a signature with a flourish. The person then tears the top sheet from the pad, puts it in an envelope, and sticks another piece of paper (known as a stamp) on the front of the envelope. Finally, the person carries the envelope outside and down the street, to a large box where the envelope is deposited. Until the turn of the 21st century, this was the monthly ritual of anyone paying a... 9 Digital Signatures: Who Really Wrote This Software? Of all the ideas we’ll encounter in this book, the concept of a “digital signature” is perhaps the most paradoxical. The word “digital,” interpreted literally, means “consisting of a string of digits.” So, by definition, anything that is digital can be copied: to do so, just copy the digits one at a time. If you can read it, you can copy it! On the other hand, the whole point of a “signature” is that it can be read, but can’t be copied (that is, forged) by anyone other than its author. How could it be possible to create a signature... 10 What Is Computable? We’ve now seen quite a number of clever, powerful, and beautiful algorithms—algorithms that turn the bare metal of a computer into a genius at your fingertips. In fact, it would be natural to wonder, based on the rhapsodic rhetoric in the preceding chapters, if there is anything that computers cannot do for us. The answer is absolutely clear if we limit ourselves to what computers can do today: there are plenty of useful tasks (mostly involving some form of artificial intelligence) that computers can’t, at present, perform well. Examples include high-quality translation between languages like English and Chinese; automatically... 11 Conclusion: More Genius at Your Fingertips? I was fortunate, in 1991, to attend a public lecture by the great theoretical physicist Stephen Hawking. During the lecture, which was boldly titled “The Future of the Universe,” Hawking confidently predicted that the universe would keep expanding for at least the next 10 billion years. He wryly added, “I don’t expect to be around to be proved wrong.” Unfortunately for me, predictions about computer science do not come with the same 10-billion-year insurance policy that is available to cosmologists. Any predictions I make may well be disproved during my own lifetime. But that shouldn’t stop us thinking about the...
No man can reveal to you aught but that which already lies half asleep in the dawning of your knowledge. The teacher who walks in the shadow of the temple, among his followers, gives not of his wisdom but rather of his faith and his lovingness. If he is indeed wise he does not bid you enter the house of his wisdom, but rather leads you to the threshold of your own mind. :: -- from his poem [[On Teaching|http://www.katsandogz.com/onteaching.html]]
No man ever steps in the same river twice, for it's not the same river and he's not the same man. Panta rhei == "all flows" Heraclitus of Ephesus
The talented, sharp (and deadpan) author and journalist Robert Wright, in his excellent book [[Nonzero|http://www.nonzero.org/]] writes about what he calls the "evolutionary escalator" and "human luck".
He describes a "gene-meme co-evolution", where biological evolution and cultural evolution move each other forward via a positive feedback mechanism.
>This sort of co-evolution can become a self-feeding process: the brainier that animals get, the better they are at creating and absorbing valuable memes; and the more valuable memes there are floating around, the more Darwinian value there is in apprehending them, so the brainier animals get.
Wright calls this a ''co-evolutionary escalator'' and says:
>Once you're on this sort of escalator, powered by the positive feedback between the two evolutions, there's no obvious reason to stop. If you don't suffer some grave, species-wide misfortune a meteor collision, say—you're probably headed for big brains and big-time culture.
And so,
>That isn't to say that our particular ancestors were destined for embarkation. Indeed, our lineage was just flat-out lucky to find itself in possession of the portfolio of key biological assets. But there's a difference between saying it took great luck for you to be the winner and saying it took great luck for there to be a winner. This is the distinction off which lotteries, casinos, and bingo parlors make their money. In the game of evolution, I submit, it was just a matter of time before one species or another raised its hand (or, at least, its grasping appendage) and said, "Bingo."...
Wright, in the introduction to the book (I love [[his introductions|Three Scientists and Their Gods - Robert Wright]] :), makes it clear ("YOU CALL THAT DESTINY?") what he means by "Destiny" in the title of the book:
>Any book with a subtitle as grandiose as "The Logic of Human Destiny" is bound to have some mealy-mouthed qualification somewhere along the way. We might as well get it over with.
>How literally do I mean the word "destiny"? Do I mean that the exact state of the world ten or fifty or one hundred years from now is inevitable, down to the last detail? No, on two counts.
>(1) I'm talking not about the world's exact, detailed state, but about its broad contours: the nature of its political and economic structures (Whither, for example, the nation-state?); the texture of individual experience (Whither freedom?); the scope of culture (Whither Mickey Mouse?); and so on.
>(2) I'm not talking about something that is literally inevitable. Still, I am talking about something whose chances of transpiring are very, very high. Moreover, I'm saying that the only real alternatives to the "destiny" that I'll outline are extremely unpleasant, best avoided for all our sakes.
So in //that// sense, where the human race is today and where it's going is our destiny (or, if you will, our "unavoidable (i.e., highly likely) luck").
US author and physician (1809 - 1894)
<<list-links "[tag{!!title}]">>
In a [[review of Thomas Nagel's book|https://www.newyorker.com/books/page-turner/thomas-nagel-thoughts-are-real]] "Mind and Cosmos: Why the Materialist ~Neo-Darwinian Conception of Nature Is Almost Certainly False", Richard Brody writes: >Nagel offers mental activity as a special realm of being and life as a special condition—in the same way that biology is a special realm of science, distinct from physics. His argument is that, if the mental things arising from the minds of living things are a distinct realm of existence, then strictly physical theories about the origins of life, such as Darwinian theory, cannot be entirely correct. Life cannot have arisen solely from a primordial chemical reaction, and the process of natural selection cannot account for the creation of the realm of mind. Biology, in his view, becomes a variety of science that is radically distinct from physics—it deals with a vast and crucial realm of phenomena that physics doesn’t and can’t encompass, precisely because they’re aspects of living things that are not physical: > >>subjective consciousness, if it is not reducible to something physical, … would be left completely unexplained by physical evolution—even if the physical evolution of such organisms is in fact a causally necessary and sufficient condition for consciousness. Nagel himself, in [[an article titled The Core of ‘Mind and Cosmos’|https://opinionator.blogs.nytimes.com/2013/08/18/the-core-of-mind-and-cosmos/]] in the New York Times, explains/clarifies: >since the long process of biological evolution is responsible for the existence of conscious organisms, and since a purely physical process cannot explain their existence, it follows that biological evolution must be more than just a physical process, and the theory of evolution, if it is to explain the existence of conscious life, must become more than just a physical theory. > >This means that the scientific outlook, if it aspires to a more complete understanding of nature, must expand to include theories capable of explaining the appearance in the universe of mental phenomena and the subjective points of view in which they occur – theories of a different type from any we have seen so far.
The Preface to his book [["The Hedgehog, the Fox, and the Magister’s Pox"|http://www.filosofia.unimi.it/zucchi/NuoviFile/Stephen%20Jay%20Gould-The%20Hedgehog,%20the%20Fox,%20and%20the%20Magister%27s%20Pox_%20Mending%20the%20Gap%20between%20Science%20and%20the%20Humanities%20%20-Belknap%20Press%20of%20Harvard%20University%20Press%20(2011).pdf]] is so captivating that the best approach is to just quote the entire thing (emphases and annotations are mine :) (BTW, I think that Gould was inspired by an essay titled [[The Hedgehog and the Fox: An Essay on Tolstoy’s View of History|https://www.blogs.hss.ed.ac.uk/crag/files/2016/06/the_hedgehog_and_the_fox-berlin.pdf]] [[written by Isaiah Berlin|On Human Nature through Isaiah Berlin's Hedgehogs and Foxes lens]]). As Gould warns us, we should not jump to the simple-minded conclusion that the "way of the fox" nor "the way of the hedgehog" are/should be associated with The Humanities and/or The Sciences. Fortunately, and delightfully, it's more nuanced than this :) !!!Introducing the Protagonists [Fox and Hedgehog] I prefer the more euphonious [pleasing to the ear] Russian beginning for fairy tales to our equivalent “once upon a time”— zhili byli (or, literally, “lived, was” [or 'there was/were']). Thus I begin this convoluted tale of initial discord and potential concord: “Zhili byli the fox and the hedgehog.” In his [[Historia animalium of 1551|https://www.nlm.nih.gov/exhibition/historicalanatomies/gesner_home.html]], Konrad Gesner, the great Swiss scholar of nearly everything, drew the initial and “official” pictures of these creatures in the first great compendium of the animal kingdom published in Gutenberg’s era. [[Gesner’s fox|https://render.fineartamerica.com/images/rendered/default/greeting-card/images-medium-5/1560-red-fox-portrait-from-conrad-gesner-paul-d-stewartscience-photo-library.jpg]] embodies the deceit and cunning traditionally associated with this important symbol of our culture—poised on his haunches, ready for anything, front legs straight and extended, hindquarters set to spring, ears cocked, and hair erect down the full line of his back. Above all, his face grins enigmatically and throughout, from the erect eyelashes to the long smirk, ending at the tapered nose with wide- spread whiskers—all seeming to say, “Watch me now, and then tell me if you’ve ever seen anything even half so clever.” [[The hedgehog|https://www.sciencesource.com/archive/Gessner--Hedgehog--16th-Century-SS2578440.html]], by contrast, is long and low, all exposed and nothing hid- den. Spines cover the entire upper surface of his body; and his small feet neatly fit under this protective mat above. The face, to me, seems simply placid: neither dumb nor disengaged but rather serenely confident in a quiet, yet fully engaged manner. I suspect that Gesner drew these two animals to emphasize these feelings and associations in a direct and purposeful way. For the Historia animalium of 1551 is not a scientific encyclopedia in the modern sense of presenting factual information about natural objects, but rather a Renaissance compendium for everything ever said or reported by human observers or moralists about animals and their meanings, with emphasis on the classical authors of Greece and Rome (seen by the Renaissance as the embodiment of obtainable wisdom in its highest form), and with factual truth and falsity as, at best, a minor criterion for emphasis. Each entry includes empirical information, fables, human uses, and stories and lists of proverbs featuring the creature in question. The fox and the hedgehog not only embodied their separate and well- known symbols of cunning versus persistence. They had also, ever since the seventh century B.C., been explicitly linked in one of the most widely known proverbs about animals, an enigmatic saying that achieved renewed life in the twentieth century. Gesner clearly drew his fox and hedgehog in their roles as protagonists in this great and somewhat mysterious motto. In Gesner’s time, and ever since for that matter, any scholar in search of a proverb would turn immediately to the standard source, the Bartlett’s beyond compare for this form of quotation: [[the Adagia|https://books.google.com/books?id=kH9XAAAAMAAJ&printsec=frontcover&source=gbs_ge_summary_r&cad=0#v=onepage&q&f=false]] (adages, or proverbs) com- piled, and first published in 1500, by the greatest intellectual of the Renaissance, [[Erasmus of Rotterdam|https://www.biography.com/people/erasmus-21291705]] (1466–1536). Gesner, of course, directly used and credited Erasmus’s exhaustive discussion of the linking proverb in both his articles, ''De Vulpe'' (on the fox) and ''De Echino'' (on the hedgehog) of his 1551 founding treatise. This somewhat mysterious proverb derives from a shadowy source, [[Archilochus|https://en.wikipedia.org/wiki/Archilochus]], the seventh-century B.C. Greek soldier-poet sometimes considered the greatest lyricist after Homer, but known only from fragments and secondary [[quotations|https://en.wikiquote.org/wiki/Archilochus]], and not from any extensive writings or biographical data. Erasmus cites, in his universalized Latin, the Archilochian contrast of fox and hedgehog: ''Multa novit vulpes, verum echinus unum magnum'' (or, roughly, “The fox devises many strategies; the hedgehog knows one great and effective strategy”). I use this well-trodden, if enigmatic, image in two important ways (and in the book’s title as well) to exemplify my concept of the proper relationship between the sciences and humanities. I could not agree more with the vital sentiment expressed by my colleague [[E. O. Wilson|https://eowilsonfoundation.org/e-o-wilson/]] (although Part III of this book will also explain my reasons for rejecting his favored path toward our common goal): “The greatest enterprise of the mind has always been and always will be the attempted linkage of the sciences and the humanities” (from his [[book Consilience|https://en.wikipedia.org/wiki/Consilience_(book)]], Knopf, 1998, page 8). I use Archilochus’s old image, and Erasmus’s extensive exegesis [critical explanation or interpretation of a text], to underscore my own recommendations for a fruitful union of these two great ways of knowing. But my comparison will not be based on the most straightforward or simpleminded comparison. That is, I emphatically do not claim that one of the two great ways (either science or the humanities) works like the fox, and the other like the hedgehog. Of my two actual usages, the first is, I confess, entirely idiosyncratic, fully concrete, and almost as enigmatic as the proverb itself. That is, I shall refer, in a crucial argument, to the specific citation of Erasmus’s explication of Archilochus’s motto as preserved in one particular copy of Gesner’s 1551 book. Moreover, although I regale you with foxes and hedgehogs in this introduction, this first usage will now disappear completely from the text until the very last pages, when I cite (and picture) this passage to make a closing general point with specific empirical oomph. As to the equally mysterious Magister who shares titular space with the fox and hedgehog, he will make a short intermediary appearance (in chapter 4) and then also withdraw until his meeting with the two animals on the closing pages. But my second usage pervades the book, although I try to keep explicit reminders to a bearable minimum (an effort demanding great forbearance, and courting probable failure in any case, from such a didactic character as yours truly). This second employment also sticks closely to the metaphorical meanings that have been grafted upon Archilochus’s image throughout history, especially since Erasmus’s scholarly exegesis. This usage became central to twentieth-century literary commentary when Isaiah Berlin—my personal intellectual hero, and a wonderful man who befriended me when I was a shy, beginning, absolute nobody—invoked the pairing of fox and hedgehog to contrast the styles and attitudes of several famous Russian writers. Ever since then, scholars have played a common game in designating their favorite (or anathematized) literati either as hedgehogs for their tenacity in sticking to one style or advocating one key idea, or as foxes for their ability to move again and again, like Picasso, from one excellence to an entirely different mode and meaning of expression. The game maintains sharp edges because these attributions have been made both descriptively and proscriptively, and people of goodwill (and bad will too, for that matter) can argue forever about either and both. (I must also confess that I named one of my books of essays An Urchin in the Storm, to designate my own stubborn invocation of Darwinian evolution as a subject to fit nearly any context or controversy. Hedgehogs, to Englishmen, are urchins.) Erasmus (and I am quoting from my 1599 edition of his [[Adagia|https://ia902701.us.archive.org/27/items/proverbschieflyt00blaniala/proverbschieflyt00blaniala.pdf]]) begins with the usual and obvious reasons for Archilochus’s famous contrast. When pursued by hunters, the fox figures out a new and sneaky way to escape each time: ''Nam vulpes multijugis dolis se tuetur adversus venatores'' (for the fox defends itself against the hunters by using many different guiles). The hedgehog, on the other hand, tries to keep out of harm’s way, but will use its one great trick if overtaken by the hunters’ dogs: the animal rolls up into a ball, with its small head and feet, and its soft underbelly, tucked up neatly and completely within the enclosing surface of spines. The dogs can do what they wish: poke the animal, roll it about, or even try to bite, but all to no avail (or to painful injury); for the dogs cannot capture such a passive and prickly ball, and must ultimately leave the animal alone, eventually (when the danger has passed) to unroll and calmly walk away. Erasmus writes: ''Echinus unica duntaxat arte tutus est adversus canum morsus, siquidem spinis suis semet involuit in pilae speciem, ut nulla ex parte morsu, prendi queat.'' (The hedgehog only has one technique to keep itself safe against the dogs’ bite, since it rolls itself up, spines outward, into a kind of ball, so that it cannot be captured by biting.) Later on in this exegesis, Erasmus even adds an old tale of intensification, delicately mentioning only the outline of the story, and referring his readers to the original sources if they wish to know more. If this one great trick seems to be failing, the hedgehog often ups the same basic ante by letting fly a stream of urine, covering the spines, and weakening them to the point of excision. But how can this dramatic form of self-imposed haircut help the creature? Erasmus goes no further, but when we turn to Pliny and Aelianus (the two classical sources cited by Erasmus), we learn what a tough and determined lit- tle bastard this apparently timid creature can be. The ultimate urine trick, we are told, can work in three possible ways. First, with the spines excised, the animal can often slither away unnoticed. Second, the urine smells so bad that the dogs or human hunters may simply lose interest and beat a quick retreat. Third, if all else fails, and the hunters take him anyway, at least the hedgehog can enjoy his last laugh in death, for his haircut has rendered him useless to his captors (who, in a fourth potential utility, might also abandon him in frus- tration by recognizing this outcome in advance)—for the main attraction of the hedgehog to humans lies in the value of his hide, but only with spines intact, as a natural brush. The power and attraction of Archilochus’s image lies, rather obviously, in its two levels of metaphorical meaning for human contrasts. The first speaks of psychological styles, often applied for quite practical goals. Scramble or persist. Foxes owe their survival to easy flexibility and skill in reinvention, to an uncanny knack for recognizing (early on, while the getting remains good) that a chosen path will not bear fruit, and that either a different route must be quickly found, or a new game entered altogether. Hedgehogs, on the other hand, survive by knowing exactly what they want, and by staying the chosen course with unswerving persistence, through all calumny and trouble, until the less committed opponents eventually drop away, leaving the only righteous path unencumbered for a walk to victory. The second, of course, speaks to favored styles of intellectual practice. Diversify and color, or intensify and cover. Foxes (the great ones, not the shallow or showy grazers) owe their reputation to a light (but truly enlightening) spread of real genius across many fields of study, applying their varied skills to introduce a key and novel fruit for other scholars to gather and improve in a particular orchard, and then moving on to sow some new seeds in a thoroughly different kind of field. Hedgehogs (the great ones, not the pedants) locate one vitally important mine, where their particular and truly special gifts cannot be matched. They then stay at the site all their lives, digging deeper (because no one else can) into richer and richer stores from a mother lode whose full generosity has never before been so well recognized or exploited. I use the fox and hedgehog as my model for how the sciences and humanities should interact because I believe that neither pure strategy can work, but that a fruitful union of these seemingly polar opposites can, with goodwill and significant self-restraint on both sides, be conjoined into a diverse but common enterprise of unity and power. The way of the hedgehog cannot suffice because the sciences and humanities, by the basic logics of their disparate enterprises, do different things, each equally essential to human wholeness. We need this wholeness above all, but cannot achieve the goal by shearing off the legitimate differences (I shall critique Wilson’s notion of consilience on this basis) that make our lives so varied, so irreducibly, and so fascinatingly, complex. But if we lose sight of the one overarching goal—the hedgehog’s insight—underneath the legitimately different concerns and approaches of these two great ways, then we are truly defeated, and the dogs of war will disembowel our underbellies and win. But the way of the fox cannot prevail either, because too great a flexibility may lead to survival of no enduring value—mere persistence with no moral or intellectual core intact. What triumph can an ultimate chameleon claim if he gains not even the world, but only his basic continuity, at the price of his soul? Fortunately, and in the most parochial American sense, we know a model of long persistence and proven utility for the virtues in fruitful union of apparent opposites. This model has sustained us through the worst fires of challenge (both voluntary self-immolation from 1861 to 1865, and attempted external prevention at several times, beginning with the first battles of 1775). We have even embodied this ideal in our national motto, ''e pluribus unum'', “one from many.” If the different skills and wondrous flexibilities of the fox can be combined with the clear vision and stubbornly singleminded goal of the hedgehog, then a star-spangled banner can protect a great expanse of maximal diversity because all the fox’s skills now finally congeal to realize the hedgehog’s great vision. Never before in human history has the experiment of democracy been tried across such a vast range of geographies, climates, ecologies, economies, languages, ethnicities, and capabilities. Lord knows we have suffered our troubles, and imposed horrendous and enduring persecutions upon sectors of the enterprise, thus sullying the great goal in the most shameful way imaginable. Yet, on balance, and by comparison to all other efforts of similar scale in human history, the experiment has worked, and has been showing substantial improvement in the course and memories of my lifetime at least. I offer the same basic prescription for peace, and mutual growth in strength, of the sciences and humanities. These two great endeavors of our soul and intellect work in different ways and cannot be morphed into one sim- ple coherence, so the fox must have his day. But the two enterprises can lead us onward together, ineluctably yoked if we wish to maintain any hope for arrival at all, toward the common goal of human wisdom, achieved through the union of natural knowledge and creative art, two different but nonconflicting truths that, on this planet at least, only human beings can forge and nurture. But I learned one other important lesson from reading Erasmus’s commentary, and by considering the deeper meaning of Gesner’s pictures. Erasmus does, following the literal lead of Archilochus’s minimality, depict the styles of the fox and hedgehog as simply different, with each strategy effective in its own way, and expressing one end of a full continuum. But Erasmus clearly favors the hedgehog in one crucial sense: foxes generally do very well indeed, but when the chips go down in extremis, look inside yourself, and fol- low the singular way that emerges from the heart and soul of your ineluctable being and construction, whatever the natural limits—for nothing beats an unswerving moral compass in moments of greatest peril. Erasmus, after praising the many wiles of the fox (as quoted above), then adds ''et tamen haud raro capitur''— “yet, nonetheless, it is captured not rarely.” The hedgehog, on the other hand, almost always emerges unscathed, a bit stressed and put-upon, perhaps, but ultimately safe nonetheless. And thus intellectuals of all stripes and tendencies must maintain this central integrity of no compromise to fashion or (far worse) to the blandishments of evil in temporary power. We have always been, and will always be, a minority. But if we roll with the punches, maintain the guts of our inner integrity, and keep our prickles high, we can’t lose—for the pen, abetted by some modern modes of dispersal, really is mightier. Finally, I don’t mean to despise or dishonor the fox, and neither does Erasmus, despite his clear zinger, quoted just above, against this ultimate symbol of wiliness. For Erasmus ends his long and scholarly commentary with two stories about dialogues between the fox and another brother carnivore. The first tale of the fox and cat simply extends Erasmus’s earlier point about the hedgehog’s edge in episodes of greatest pith and moment. The two animals meet and begin to argue about better ways to elude packs of hunting dogs. The fox brags about his enormous bag of tricks, while the cat describes his single effective way. Then, right in the midst of this abstract discussion, the two creatures must face an unexpected and ultimately practical test: “Suddenly, amidst the dispute, they hear the voices of the dog pack. The cat immediately leaps up into the highest tree, but the fox, meanwhile, is surrounded and captured by the crowd of dogs.” ''Praestabilius esse nonnunquam unicum habere consilium'' (perhaps it is better to have one way of wisdom), Erasmus adds, ''id sit verum et efficax'' (provided that it be true and effective). But the second tale of the fox and panther saves our maligned character and shows the inner beauty of his flexibility, as illustrated by his avoidance of mere gaudy show for true dexterity of mind. Erasmus writes: ''Cum aliquando pardus vulpem pre se contemneret, quod ipse pellem haberet omnigenus colorum maculis variegatem, respondit vulpes, sibi decoris in animo esse, quod ille esset in cute.'' “When the panther disparages the fox by comparison to himself, because his [the panther’s] skin is so beautifully variegated with so many colored spots of all kinds, the fox responds that it is better to be so decorated in the mind than upon the skin.” And so I say to the sciences (where I reside with such lifelong pride and satisfaction) and to the humanities (whose enduring technique of exegesis from printed classical sources I try, in my own conceit, to utilize as the primary mode of analysis in this book): what a power we could forge together if we could all pledge to honor both of our truly different and equally necessary ways, and then join them in full respect, in the service of a common goal as expressed in old Plato’s definition of art as intelligent human modification and wondrous ornamentation, based on true veneration of nature’s reality. For then, as the Persian poet said: :: Oh wilderness were Paradise enow. Then wilderness (nature’s unvarnished tangle of wonders) would become a paradise (literally, a cultivated garden of human delight). The goal could not be greater or more noble, but the tensions are old and deep, however falsely construed from the start, and stirred up by small minds ever since. Thus the union of the fox and hedgehog can certainly be accomplished, and would surely yield, as progeny, a many-splendored thing called love and learning, creativity and knowledge. But we had best proceed, in this hybridization, by the resolution of a bad old joke about an animal not closely related to the hedgehog, but functionally equivalent in the primary manner of this discussion. How, using more decorous language than the joke enjoins, can two porcupines copulate? The answer, of course, is “carefully". """ """ (See also what [[David Epstein writes about Vertical vs. Lateral Thinkers|Range - Why generalists triumph in a specialized world - by David Epstein]], or Birds vs. Frogs per Freeman Dyson).
Poe's [["The Purloined Letter"|http://etc.usf.edu/lit2go/147/the-works-of-edgar-allan-poe/5357/the-purloined-letter/]] has an epigraph by Seneca
>Nil sapientiae odiosius acumine nimio.
[There is nothing wisdom hates more than cleverness]
which is not just true (in many cases) but also wise :)
Seneca's actually reminded me of a witty question in Hebrew, which I think is in the same spirit:
Q: what is the difference between a wise person and a clever one?
A: A clever [smart] person can figure out how to get out of a tough situation, which a wise person would never even get into.
It's a short "detective story", where in it the "wise" Dupin is more successful in solving a mystery than the "clever" police Prefect Monsieur G.
As Dupin explains to the author how he solved the case, he berates mathematicians and mathematics by saying, for example:
* The mathematics are the science of form and quantity; mathematical reasoning is merely logic applied to observation upon form and quantity.
** partly true. Mathematics is much more than algebra and logic, and is not limiting itself to "observation upon form and quantity".
* The great error lies in supposing that even the truths of what is called pure algebra, are abstract or general truths. And this error is so egregious that I am confounded at the universality with which it has been received.
** only vain and technocratic (mathocratic?) mathematicians would claim that algebra reflects general truths about the world.
* What is true of relation—of form and quantity—is often grossly false in regard to morals, for example. In this latter science it is very usually untrue that the aggregated parts are equal to the whole. In chemistry also the axiom fails. In the consideration of motive it fails; for two motives, each of a given value, have not, necessarily, a value when united, equal to the sum of their values apart.
** different branches of mathematics definitely realize the limitations and applicability of math to realistic situations. But math is making constant advances in helping gain clarity or at least insights into real-world situations and conditions (e.g., statistics, probability, calculus).
* But the mathematician argues, from his finite truths, through habit, as if they were of an absolutely general applicability—as the world indeed imagines them to be. Bryant, in his very learned ‘Mythology,’ mentions an analogous source of error, when he says that ‘although the Pagan fables are not believed, yet we forget ourselves continually, and make inferences from them as existing realities.’ With the algebraists, however, who are Pagans themselves, the ‘Pagan fables’ are believed, and the inferences are made, not so much through lapse of memory, as through an unaccountable addling of the brains.
** again, certain mathematicians may believe certain things and behave in a certain way, but this doesn't necessarily represent truly what math is about.
Is Poe making the same mistake he is accusing the mathematicians of making, namely "non distributio medii" [A logical fallacy that is committed when the middle term in a categorical syllogism isn't distributed.]?
In the story, Dupin accuses the Prefect of thinking that since
>his [the Prefect's] defeat lies in the supposition that the Minister [the criminal] is a fool, because he has acquired renown as a poet. All fools are poets; this the Prefect feels;
I'm not familiar enough with Poe to say if he (consistently? often?) has (deep? some?) criticism of math/logic/mathematicians, or if it's just in this story, as reflected in Dupin's position.
It is true that some "great minds" in physics and math (for example, Eugene Wigner, or Richard Hamming, or Frank Wilczek) had pondered "[[The Unreasonable Effectiveness of Mathematics]]" (and logic) in the real world, but I think that Poe may have taken too simple a view of it (narrowly focusing on the limitations/inapplicability of algebra, axioms, and basic deductive logic).
But Poe (1809-1849) definitely hit on something which C. P. Snow (in 1959) called [["The Two Cultures"|https://en.wikipedia.org/wiki/The_Two_Cultures]], and others (e.g., Stephen Jay Gould's [["The Hedgehog, the Fox, and the Magister's Pox"|https://en.wikipedia.org/wiki/The_Hedgehog,_the_Fox,_and_the_Magister%27s_Pox]]. (see [[the preface|On "The Hedgehog, the Fox, and the Magister’s Pox" by Stephen Jay Gould]])) pointed out as a societal/cultural problem, too.
In Poe's story, it seems he values "psychological" insight and knowledge/wisdom (which as you can imagine, I don't have a problem with :) but his Dupin definitely uses logic and deduction combined with psychology.
Poe's Dupin criticizes mathematicians as "technocratic" and "arrogant". C. P. Snow calls the "humanists" (as opposed to the "scientists") "natural Luddites". I'm sure there is lack of understanding and probably lack of respect on both sides ("cultures"). But some "luminaries" (e.g., Albert Einstein, or Richard Feynman, or Carl Sagan) pointed out that if anything, honest scientists and true science actually make us humble and inspire us with awe. And others (e.g., Paula Marantz Cohen) articulated [[why the "humanities" are essential and vital to our species|On the importance of being educated in the Humanities (and the Sciences :)]].
And this, I think, is the real "trick" in becoming wise (and not just clever): we need to learn how to use __all__ tools available to us in the "human toolbox" and be aware and cautious about their strengths, weaknesses, and inherent faliability!
Nick Bostrom (professor, Faculty of Philosophy, Oxford University) covers the [[anthropic bias|http://www.anthropic-principle.com/?q=book/table_of_contents]] (see also [[the anthropic principle|http://en.wikipedia.org/wiki/Anthropic_principle]] and [[The "astonishing skills" of a coin flipper]]) on [[his website|http://www.anthropic-principle.com/]], starting with a clear and concise "hook": >It appears that there is a set of fundamental physical constants that are such that had they been very slightly different, the universe would have been void of intelligent life. It's as if we're balancing on a knife’s edge. Some philosophers and physicists take the 'fine-tuning' of these constants to be an explanandum that cries out for an explanans, but is this the right way to think? > >The data we collect about the Universe is filtered not only by our instruments' limitations, but also by the precondition that somebody be there to “have” the data yielded by the instruments (and to build the instruments in the first place). This precondition causes observation selection effects - biases in our data that may call into question how we interpret evidence that the Universe is fine-tuned at all. [[Janna Levin|http://jannalevin.com/bio-and-contact/]] (astrophysicist and theoretical cosmologist, Columbia University), in an [[interview with Krista Tippett|https://www.brainpickings.org/2015/01/09/krista-tippett-einsteins-god-janna-levin/]] observes the following (from a scientist's and atheist's perspective): >Our convincing feeling is that time is absolute. Our convincing feeling is that there should be no limit to how fast you can travel. Our convincing feelings are based on our experiences because of the size that we are, literally, the speed at which we move, the fact that we evolved on a planet under a particular star. So our eyes, for instance, are at peak in their perception of yellow, which is the wave band the sun peaks at. It’s not an accident that our perceptions and our physical environment are connected. We’re limited, also, by that. That makes our intuitions excellent for ordinary things, for ordinary life. That’s how our brains evolved and our perceptions evolved, to respond to things like the Sun and the Earth and these scales. And if we were quantum particles, we would think quantum mechanics were totally intuitive. Things fluctuating in and out of existence, or not being certain of whether they’re particles or waves — these kinds of strange things that come out of quantum theory — would seem absolutely natural… > >Our intuitions are based on our minds, our minds are based on our neural structures, our neural structures evolved on a planet, under a sun, with very specific conditions. We reflect the physical world that we evolved from. It’s not a miracle. In the Tippett interview, Levin also makes the connections with math and spirituality/religion: >If I were to ever lean towards spiritual thinking or religious thinking, it would be in that way. It would be, why is it that there is this abstract mathematics that guides the universe? The universe is remarkable because we can understand it. That’s what’s remarkable. All the other things are remarkable, too. It’s really, really astounding that these little creatures on this little planet that seem totally insignificant in the middle of nowhere can look back over the fourteen-billion-year history of the universe and understand so much and in such a short time. > >So that is where I would get a sense, again, of meaning and of purpose and of beauty and of being integrated with the universe so that it doesn’t feel hopeless and meaningless. Now, I don’t personally invoke a God to do that, but I can’t say that mathematics would disprove the existence of God either. It’s just one of those things where over and over again, you come to that point where some people will make that leap and say, “I believe that God initiated this and then stepped away, and the rest was this beautiful mathematical unfolding.”^^1^^ And others will say, “Well, as far back as it goes, there seem to be these mathematical structures. And I don’t feel the need to conjure up any other entity.” And I fall into that camp, and without feeling despair or dissatisfaction. This seems to be related to the question of "is mathematics a human invention or discovery?". Here is [[Richard Hamming's explanations of the unreasonable effectiveness of mathematics|On why Math works for us]], which, I think, boils down to ''We see what we look for'': >we approach the situations with an intellectual apparatus so that we can only find what we do in many cases. It is both that simple, and that awful. What we were taught about the basis of science being experiments in the real world is only partially true. Eddington went further than this; he claimed that a sufficiently wise mind could deduce all of physics. I am only suggesting that a surprising amount can be so deduced. Eddington gave a lovely parable to illustrate this point. He said, "Some men went fishing in the sea with a net, and upon examining what they caught they concluded that there was a minimum size to the fish in the sea." (see [[Simpson's paradox]]). The last parable is [[referenced by Bostrom|http://www.anthropic-principle.com/?q=book/chapter_1#1a]], too: > How big is the smallest fish in the pond? You catch one hundred fishes, all of which are greater than six inches. Does this evidence support the hypothesis that no fish in the pond is much less than six inches long? Not if your net can’t catch smaller fish. > >Knowledge about limitations of your data collection process affects what inferences you can draw from the data. In the case of the fish-size-estimation problem, a selection effect—the net’s sampling only the big fish—vitiates any attempt to extrapolate from the catch to the population remaining in the water. Had your net instead sampled randomly from all the fish, then finding a hundred fishes all greater than a foot would have been good evidence that few if any of the fish remaining are much smaller. ---- ^^1^^ or as [[Sallustius had written|https://en.wikiquote.org/wiki/Sallustius]] in the 4^^th^^ century: All this care for the world, we must believe, is taken by the Gods without any act of will or labor.
In a delightful math book titled //Chases and Escapes// by Paul J. Nahin (see [[the introduction|http://press.princeton.edu/chapters/i9700.pdf]]), he starts by saying that > not all pursuit problems have complicated answers. and he quotes [[John R. Isbell|https://en.wikipedia.org/wiki/John_R._Isbell]] giving an example: > If E is an evader with speed s1 and P is a pursuer with speed s2 > s1, then "Of course P can catch E [no matter what E does], at least by going to his [E's] initial position and [simply] following his path. Now, ain't //that// iron-clad logic ... :) In chapter 1 Nahin analyzes a case of a pirate ship chasing a merchant ship. The Merchant is moving in a straight line and the pirates are approaching it at a higher speed. It turns out that in this situation there is an [[Apollonius Circle|https://en.wikipedia.org/wiki/Circles_of_Apollonius]] which shows the exact intercept/take-over location (Apollonius Circle on the left, start chase and end chase simulations on the right: Green = Merchant ship, Red = Pirate Ship, Blue = Apollonius Circle): |borderless|k |[img[pursuit calculation|./resources/pursuit calc 1.png][./resources/pursuit calc.png]]|Chase start:[img[pursuit start|./resources/pursuit start 1.png][./resources/pursuit start.png]]|Chase end (interception):[img[pursuit end|./resources/pursuit end 1.png][./resources/pursuit end.png]]| |borderless|k Graphing of Apollonius Circle ([[Trinket|https://trinket.io/library/trinkets/4d0cbcc594]]), Simulation of Pursuit ([[Trinket|https://trinket.io/library/trinkets/7f159598a0]])
In an [[article titled Elegance by Matthew Fuller|https://aestech.wikischolars.columbia.edu/file/view/Fuller+-+Elegance+(Software+Studies).pdf]] he gives the following description and requirements for elegant computer programs/solutions (the breakdown/itemization is mine): >In Literate Programming, Donald Knuth suggests that the best programs can be said to possess the quality of elegance. Elegance is defined by four criteria: ** the leanness of the code; ** the clarity with which the problem is defined; ** spareness of use of resources such as time and processor cycles; and, ** implementation in the most suitable language on the most suitable system for its execution. >Such a definition of elegance shares a common vocabulary with design and engineering, where, in order to achieve elegance, use of materials should be the barest and cleverest. The combination is essential—too much emphasis on one of the criteria leads to clunkiness or overcomplication. It is interesting and relevant that Fuller mentions Gregory Chaitin and his work on [[efficiency, complexity, and elegance|On randomness, compression, and theory effectiveness (and complexity)]]. Chaitin is looking (for example, in his article [[Doing Mathematics Differently|http://inference-review.com/article/doing-mathematics-differently]]) at brevity of the solution/program, but like any other complex things, this question/aspect is a central one in programming and implementation: sometimes shortness is not the most important aspect. ''As the [[Zen of Python|https://www.python.org/dev/peps/pep-0020/]] (by Tim Peters ([[import this|http://stackoverflow.com/questions/5855758/what-is-the-source-code-of-the-this-module-doing]])) emphasizes'': Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. (Since elegance goes hand-in-hand with clarity, and in my opinion, explanatory power, here is [[an example tying these concepts/practices together|On transparent and explanatory modeling]]). Related to this, [[here is some advice|https://go-proverbs.github.io/]] in the form of (Simple, Poetic, Pithy) "proverbs" from a different culture/language (the [[Go programming language|https://golang.org/]]), with [[some interpretations by Sarah Allen |https://www.ultrasaurus.com/2016/07/go-language-philosphy-thorugh-proverbs/]]: The bigger the interface, the weaker the abstraction. A little copying is better than a little dependency. Clear is better than clever. Reflection is never clear. Don't just check errors, handle them gracefully. Design the architecture, name the components, document the details. Documentation is for users. Don't panic.
In Maria Popova's blogpost [[Kierkegaard on time|https://www.brainpickings.org/2017/04/18/kierkegaard-concept-of-anxiety-time/]], she quotes the great Danish philosopher:
>The moment is not properly an atom of time but an atom of eternity.
and this, I think, perfectly captures the idea that ''concepts are not reality''. What I mean by that is that, we all accept (since we heard it from childhood) that a moment is not a well-defined duration of time, i.e., it is subjective (to one person a moment may mean 'about a second', while to another it may mean 'less than a minute', and so on :)
But, a moment can be 'any length of time' only if it is part of something (or a slice, if you will) that is also not well-defined, or very elastic; which is what eternity (in Kierkegaard's quote) is.
We all accept that eternity is not real; it is a concept (and the brilliant (but odd) mathematician [[Georg Cantor|https://en.wikipedia.org/wiki/Georg_Cantor]] proved it by [[mathematically defining an infinite family of infinites|http://gizmodo.com/5809689/a-brief-introduction-to-infinity]], one mind-blowingly bigger than the next). It is a useful concept, in the sense that it better helps us know, learn, and deal with reality (as well as work and manipulate other concepts), __but__ it is not real, i.e., infinity (and for that matter, a moment) does not exist (is not part of reality).
Kierkegaard puts it nicely:
>If in the infinite succession of time [the "timeline": from past through present, into the future] a foothold could be found, i.e., a present, which was the dividing point, the division would be quite correct. However, precisely because every moment, as well as the sum of the moments, is a process (a passing by), no moment is a present, and accordingly there is in time neither present, nor past, nor future.
We (humans) perceive (and conceive of) time as a change in our reality. Kierkegaard calls it "spatializing", and Einstein created/defined "space-time" to describe our experiencing of this process.
The elusiveness (non-reality?) of time is also reflected in physics, the science invented by us to help us understand and deal with reality, in the fact that some phenomena, especially in Einstein's theories and sub-atomic theories. As Philip Cheung [[writes in an article|https://www.quantamagazine.org/a-debate-over-the-physics-of-time-20160719/]]:
>Many physicists argue that Einstein’s position is implied by the two pillars of modern physics: Einstein’s masterpiece, the general theory of relativity, and the Standard Model of particle physics. The laws that underlie these theories are time-symmetric — that is, the physics they describe is the same, regardless of whether the variable called “time” increases or decreases. Moreover, they say nothing at all about the point we call “now” — a special moment (or so it appears) for us, but seemingly undefined when we talk about the universe at large.
In another insightful post on Brainpickings [[The Science of How Our Social Interactions Shape Our Experience of Time|https://www.brainpickings.org/2017/09/04/alan-burdick-why-time-flies-empathy/]], Popova covers a new book by Alan Burdick titled "Why Time Flies: A Mostly Scientific Investigation", and quotes the physicist Stephen Hawking (investigating black holes and the origins of the universe), who had commented on the question of "what was there __before__ the Big Bang?" and "Did time not exist before that?":
>[It] is like standing at the South Pole and asking which way is south: “Earlier times simply would not be defined.”
In Burdick's book he points out that due to our conception of time, we speak of "making time" and "wasting time", too much of it, and too little of it, its preciousness, and so on. But time, again, is not reality, but a very useful tool (one of many) for dealing with it.
And how is all of this related to Computer Science, you may ask?
Well, all of computer science relies on layers upon layers of abstraction and concepts we defined and created above and on top of physical reality. Computers are made of hardware (physical entities) on top of which we create logic operations ("logic gates"), which are the basis for numerical operations ("binary calculations"), which are the basis (lower layers) of primitive programming operations ("machine languages"), which enable high-level programming languages, models, simulations, virtual realities (!), and so on. A long chain of concepts and abstractions, none of which is "actual reality".
There are many implications to this, and many dangers if we confuse (or intentionally blur) the difference between concepts and reality, like for example when we say that "algorithms are ruling our lives", or "the software bug/glitch was responsible for the accident", etc. At bottom, the concepts (ha!) of morality, responsibility, accountability, compassion, justice, etc., are (again) human tools (or means) for dealing with reality. It doesn't help to assign or relegate these concepts to another set of concepts. It only muddles the water.
!!!One Dimensional (or Elementary) Cellular Automata and Creativity An [[article|http://arxiv.org/pdf/1305.2537.pdf]] trying to link between One Dimensional (or Elementary) ''Cellular Automata and Creativity'', the following classification was made. From the abstract: >We map cell-state transition rules of elementary cellular automata (ECA) onto the cognitive control versus schizotypy spectrum phase space and interpret cellular automaton behaviour in terms of creativity. To implement the mapping we draw analogies between a degree of schizotypy and generative diversity of ECA rules, and between cognitive control and robustness of ECA rules (expressed via Derrida coefficient). We found that null and fixed point ECA rules lie in the autistic domain and chaotic rules are 'schizophrenic'. There are no highly articulated 'creative' ECA rules. Rules closest to 'creativity' domains are two-cycle rules exhibiting wave-like patterns in the space-time evolution. |>|>|!Four classes of CA creativity| |bgcolor(lightblue): Class |bgcolor(lightblue): Rules^^1^^ | |Creative| 3, 5, 11, 13, 15, 35 | |Schizophrenic| 9, 18, 22, 25, 26, 28, 30, 37, 41, 43, 45, 54, 57, 60, 62, 73, 77, 78, 90, 94, 105, 110, 122, 126, 146, 150, 154, 156 | |Autistic savants| 1, 2, 4, 7, 8, 10, 12, 14, 19, 32, 34, 42, 50, 51, 76, 128, 136, 138, 140, 160, 162, 168, 170, 200, 204 | |Severely autistic| 23, 24, 27, 29, 33, 36, 40, 44, 46, 56, 58, 72, 74, 104, 106, 108, 130, 132, 142, 152, 164, 172, 178, 184, 232 | !!!Cognitive Cellular Automata An [[article|resources/Mandik - Cognitive Cellular Automata.pdf]] covering questions of ''Cognitive Cellular Automata''. From the abstract: >In this paper I explore the question of how artificial life might be used to get a handle on philosophical issues concerning the mind-body problem. I focus on questions concerning what the physical precursors were to the earliest evolved versions of intelligent life. I discuss how cellular automata might constitute an experimental platform for the exploration of such issues, since cellular automata offer a unified framework for the modeling of physical, biological, and psychological processes. I discuss what it would take to implement in a cellular automaton the evolutionary emergence of cognition from non-cognitive artificial organisms. I review work on the artificial evolution of minimally cognitive organisms and discuss how such projects might be translated into cellular automata simulations. !!!Cellular Automata and emergence, free will, and computation Another [[article|http://plato.stanford.edu/entries/cellular-automata/]] starting with some CA basics and discussing interesting philosophical topics like ''emergence, free will, and computation'' From the content: Introductory section of CA - a brief survey and explanation via an example A section on the general theory of CA, together with a selection of computational and complexity-theoretic results in the field A section describing some uses of CA as tools for philosophical investigation, and surveys ways in which they can raise new philosophical questions ------ ^^1^^ Using [[Wolfram's classification of Elementary One Dimensional Cellular Automata (1D CA, ECA)|http://mathworld.wolfram.com/ElementaryCellularAutomaton.html]]
>What we hope ever to do with ease, we must learn first to do with diligence. ::-- Samuel Johnson A [[short and clear article|https://www.fs.blog/2012/07/what-is-deliberate-practice/]] on the [[Farnam Street Blog|https://www.fs.blog/]] summarizes a key element in effective and meaningful learning and performance: deliberate practice. The end goal is to get to [[the highest level of competence|The Four Stages of Competence]]. It defines Deliberate Practice as an activity which is > designed specifically to improve performance, often with a teacher's help; it can be repeated a lot; feedback on results is continuously available; it's highly demanding mentally, whether the activity is purely intellectual, such as chess or business-related activities, or heavily physical, such as sports; and it isn't much fun. and it breaks it up into its components: * ''Designed to Improve Performance'' - The word designed is key. While enjoyable, practice lacking design is play and doesn’t offer improvement. ** In theory, with the right motivations and some expertise, you can design a practice yourself. ** Teachers, or coaches, see what you miss and make you aware of where you're falling short. ** With or without a teacher, great performers deconstruct elements of what they do into chunks they can practice. They get better at that aspect and move on to the next. * ''Repeated (a lot)'' - Repetition inside the comfort zone does not equal practice. Deliberate practice requires that you should be operating in the learning zone and you should be repeating the activity a lot with feedback. ** Most of the time we’re practicing we’re really doing activities in our __comfort zone__. This doesn’t help us improve because we can already do these activities easily. ** On the other hand, operating in the __panic zone__ leaves us paralyzed as the activities are too difficult and we don't know where to start. ** The only way to make progress is to operate in the __learning zone__, which are those activities that are just out of reach. * ''Feedback on results is continuously available'' - Feedback gets a little tricky when you must subjectively interpret the results. While you don't need a coach, this can be an area they add value. * ''Mentally Demanding'' - Doing things we know how to do is fun and does not require a lot of effort. Deliberate practice, however, is not fun. Breaking down a task you wish to master into its constituent parts and then working on those areas systematically requires a lot of effort. ** "The work is so great that it seems no one can sustain it for very long. A finding that is remarkably consistent across disciplines is that four or five hours a day seems to be the upper limit of deliberate practice, and this is frequently accomplished in sessions lasting no more than an hour to ninety minutes." The article concludes with an interesting observation by an introvert: In her book, //Quiet: The Power of Introverts in a World That Can't Stop Talking//, [[Susan Cain|https://www.quietrev.com/author/susan-cain/]] writes: >Deliberate Practice is best conducted alone for several reasons. It takes intense concentration, and other people can be distracting. It requires deep motivation, often self-generated. But most important, it involves working on the task that’s most challenging to you personally. Only when you’re alone, Ericsson told me, can you “go directly to the part that’s challenging to you. If you want to improve what you’re doing, you have to be the one who generates the move. Imagine a group class—you’re the one generating the move only a small percentage of the time.”
From an excellent article by the psychologist Jerome Bruner titled [["The Act of Discovery"|https://digitalauthorshipuri.files.wordpress.com/2015/01/the-act-of-discovery-bruner.pdf]]: >I am suggesting that there are forms of activity that serve to enlist and develop the competence motive, that serve to make it the driving force behind behavior. I should like to add to White's general premise [Robert White (R. W. White, 1959)] that the exercise of competence motives has the effect of strengthening the degree to which they gain control over behavior and thereby reduce the effects of extrinsic rewards or drive gratification. > >The brilliant Russian psychologist Vigotsky (L. S. Vigotsky, 1934) characterizes the growth of thought processes as starting with a dialogue of speech and gesture between child and parent; autonomous thinking begins at the stage when the child is first able to internalize these conversations and "run them off" himself. This is a typical sequence in the development of competence. > >So too in instruction. The narrative of teaching is of the order of the conversation. The next move in the development of competence is the internalization of the narrative and its "rules of generation" so that the child is now capable of running off the narrative on his own. The hypothetical mode in teaching by encouraging the child to participate in "speaker's decisions" speeds this process along. > >Once internalization has occurred, the child is in a vastly improved position from several obvious points of view -- notable that he is able to go beyond the information he has been given to generate additional ideas that can either be checked immediately from experience or can, at least, be used as a basis for formulating reasonable hypotheses. This continuous construction of hypotheses and checking them against the real world/environment is what Seymour Papert also advocated when talking about using Logo to [[develop mathematical knowledge|An Exploration in the Space of Mathematics Educations]] (in [[a constructionist manner|A Papertian constructionist alternative learning environment]]). >But over and beyond that, the child is now in a position to experience success and failure not as a reward and punishment, but as information. For when the task is his own rather than a matter of matching environmental demands, he becomes his own paymaster in a certain measure. Seeking to gain control over his environment, he can now treat success as indicating that he is on the right track, failure as indicating he is on the wrong one. This last part, I think is similar to what the psychologist Carol Dweck developed around [["growth mindset" vs. "fixed mindset"|https://fs.blog/2015/03/carol-dweck-mindset/]]. > >In the end, this development has the effect of freeing learning from immediate stimulus control. When learning in the short run leads only to pellets of this or that rather than to mastery in the long run, then behavior can be readily "shaped" by extrinsic rewards. When behavior becomes more long-range and competence-oriented, it comes under the control of more complex cognitive structures, plans and the like, and operates more from the inside out. And Bruner concludes this point: >To sum up the matter of the control of learning, then, I am proposing that the degree to which competence or mastery motives come to control behavior, to that degree the role of reinforcement or "extrinsic pleasure" wanes in shaping behavior. > >The child comes to manipulate his environment more actively and achieves his gratification from coping with problems. Symbolic modes of representing and transforming the environment arise and the importance of stimulus-response-reward sequences declines. > >To use the metaphor that David Riesman developed in a quite different context, mental life moves from a state of outer-directedness in which the fortuity of stimuli and reinforcement are crucial to a state of inner-directedness in which the growth and maintenance of mastery become central and dominant.
From an article by Mitchel Resnick (the MIT professor of Logo, Lego Mindstorms, and Scratch fame) titled [["GIVE P’S A CHANCE: PROJECTS, PEERS, PASSION, PLAY"|https://web.media.mit.edu/~mres/papers/constructionism-2014.pdf]], he describes four principles guiding his [[Lifelong Kindergarten Group|https://www.media.mit.edu/groups/lifelong-kindergarten/overview/]] when designing and building learning frameworks and environments which encourage and engage young learners to grow to be creative thinkers.
On the importance of thinking creatively Resnick writes:
>We live in a world that is changing more rapidly than ever before. Today’s children will face a continual stream of new issues and unexpected challenges in the future. Many things that they learn today will be obsolete tomorrow. To thrive, they must learn to design innovative solutions to the unexpected problems that will undoubtedly arise in their lives. Their success and satisfaction will be based on their ability to think and act creatively. Knowledge alone is not enough: they must learn how to use their knowledge creatively [and across disciplines].
He describes a spiraling learning process (inspired by kindergarten, as reflected in the title of another article: [[All I Really Need to Know (About Creative Thinking) I Learned (By Studying How Children Learn) in Kindergarten|https://web.media.mit.edu/~mres/papers/kindergarten-learning-approach.pdf]]^^1^^ :)
>a spiraling cycle of Imagine, Create, Play, Share, Reflect, and back to Imagine – is ideally suited to the needs of the 21st century, helping learners develop the creative-thinking skills that are critical to success and satisfaction in today’s society.
[>img[spiraling learning|resources/Resnick spiraling learning.png]]
This is
>a spiraling process in which children imagine what they want to do, create a project based on their ideas, play with their creations, share their ideas and creations with others, reflect on their experiences – all of which leads them to imagine new ideas and new projects.
And the "Four P's of Creative Learning" (guiding principles):
* ''Projects.'' People learn best when they are actively working on meaningful projects – generating new ideas, designing prototypes, refining iteratively.
* ''Peers.'' Learning flourishes as a social activity, with people sharing ideas, collaborating on projects, and building on one another’s work.
* ''Passion.'' When people work on projects they care about, they work longer and harder, persist in the face of challenges, and learn more in the process.
* ''Play.'' Learning involves playful experimentation – trying new things, tinkering with materials, testing boundaries, taking risks, iterating again and again.
** There is a difference between a ''playpen'' and a ''playground'': a __playpen__ is a restrictive environment, which usually/often suffers from lack of freedom to experiment, lack of autonomy for exploration, lack of creative opportunities, and lack of risks. A __playground__ provides opportunities for freedom, exploration, experimentation, and collaboration. A playground promotes a sense of mastery, creativity, self-confidence, and open exploration.
** Resnick uses terms like tinkerers, planners, ''patterners'', and ''dramatists''. The latter two terms were coined by education researchers Dennie Wolf and Howard Gardner in the 1970s. __Patterners__, are fascinated by structures and patterns, and they typically enjoy playing with blocks and puzzles. __Dramatists__ are more interested in stories and social interaction, and they often play with dolls and stuffed animals. A single set of toys can be designed to serve both groups, but play scenarios should be framed differently depending on the intended audience.
These four P’s are strongly aligned with (and inspired by) the Constructionist approach to education, which emphasizes the value of learners playfully creating personally-meaningful projects in collaboration with peers ([[a-la Seymour Papert|A Papertian constructionist alternative learning environment]]).
!!! From Mitchel Resnick's book "Lifelong Kindergarten"
!!!! About creativity
* __Misconception 1__ - Creativity is about artistic expression. Not true. Scientists, doctors, engineers, social workers, politicians, and more can //and should// be creative. A better name for what is meant in the book (and the activities with Scratch) is ''Creative Thinking''.
* __Misconception 2__ - Only a small segment of the population is creative. Not true. Many people have and use "small-c creativity" (as opposed to "~Big-C Creativity". Everyone can be "small-c creative" and we should help everyone to reach their full creative potential.
* __Misconception 3__ - Creativity comes in a flash of insight. Not true. As Thomas Edison said "creativity is 1% inspiration and 99% perspiration". But it's not just sheer hard work, but rather hard work with curiosity, playfulness, experimentation, and disciplined investigation and practices.
* __Misconception 4__ - You can't teach creativity. Not true. It's true that "teaching" using rigid rules and structures suppresses creativity, but creativity can definitely be nurtured, encouraged, and supported, since we are all born curious, playful, and imaginative.
!!!! Tensions and tradeoffs about __technology__
* There is tension between "techo-enthusiasts" ('technology in education is only improving things, and the newer, the better') and "techno-skeptics" (technology in education should be avoided, we should get back to basics). Technology should be used wisely, and instead of trying to "minimize screen time" we should try to "maximize creative time". The focus shouldn't be on which technologies should or should not be used, but on what learners will do with these technologies.
!!!! Tensions and tradeoffs about __knowledge__
* There is tension between the desire to "first teach the basics and lay a strong foundation of knowledge, followed by more advanced/engaging and deep knowledge/application" and the desire to "dive into more advanced/engaging projects, and learning whatever is needed as it is needed to the depth needed (just-in-time)".
* the danger of laying a foundation first, is that students learn without a clear and compelling context, so they may learn disconnected pieces of knowledge" and will find it hard to apply correctly in the right context/circumstances or in new situations.
* A project-based approach teaches knowledge in context, but also knowledge acquisition strategies, knowledge "networks" and links/connections, while harnessing learners' passion and interests, resulting in high engagement, creativity, effort, and results.
!!!! Tensions and tradeoffs about __structure__
* Working on projects based on interest (as opposed to based on an age/grade, subject area, curriculum) is also a type of structure. It requires working with like-minded learners, being mentored/helped by more experienced learners and/or teachers, balancing data/knowledge acquisition with experimentation, building/testing, refining/improving/enhancing, and so on, all of which are a form of structure/process, methodology, etc.
* The projects themselves can have structure; for example, they can be "close-started" while being "open-ended" (with some scaffolding and restrictions at the beginning, but no restrictions on pursuing interests, ideas, goals over time.
!!!! Tensions and tradeoffs about __expertise__
* Good teachers and mentors should be able to move fluidly between various roles:
** __Catalyst__ - provide 'sparks' that accelerate the learning process (by asking questions, showing examples)
** __Consultant__ - be "a guide on the side, not a sage on the stage". Be technical consultants, or creative consultants, or emotional supporters (not answer providers or instruction deliverers).
** __Connector__ - connect learners with other people and resources to help them make progress on their projects towards their goals.
** __Collaborator__ - work on their own projects or areas of interest, thus blurring the boundaries between teaching and learning, practicing and demonstrating life-long-learning.
* There is a tension between the desire to do "discovery learning" with peers, where knowledge is '(re)invented', and the desire to have experts tell and teach the needed and known (and correct/established) knoeldge.
** learning with and from peers isn't enough. Experts are sometimes very needed and very useful for learning. It is important to provide expertise when needed, but equally important is to teach learners how to seek and find the expertise they need if/when they need it.
!!!! Tensions and tradeoffs about __assessment__
* Standardized exams/tests/assessments are useful, since they provide accountability (are money and other resources spent well?), feedback for teachers (are the teaching methods effective?), feedback for students (are there misunderstandings and misconceptions?)
* Standardized exams measure certain, possibly important things, but can they measure other not less important things, like the ability to think and do creatively. ("not everything countable counts, and not everything that counts is countable").
* just measuring the measurable (or the easily measurable) may distort priorities and misguide actions/plans ("we treasure what we measure"). We need to be "evidence-based", but assess not just the quantifiable.
* Rather than just ''measure'' what learners learn (through numbers), we need to also ''document'' what they have learned (through compelling examples).
** that's where project documentation, reflection, portfolios are important.
!!! Ten Tips for Learners
The following list was generated by a group of kids in one of the Life-long Learning workshops.
* 1. __Start simple__ - try out a simple version, then extend and improve it.
* 2. __Work on things that you like__ - "interests are a natural resource that fuels learning".
* 3. __If you have no clue what to do, fiddle around__ - it's OK not to have a goal or a plan when you get started. Sometimes the best ideas arise through tinkering.
* 4. __Don't be afraid to experiment__ - following instructions is useful for certain things, and will teach you certain important skills. But to become a creative thinker, you must be willing to experiment, to try new things, to ignore conventional wisdom.
* 5. __Find a friend to work with and share ideas__ - you might collaborate directly on an entire project, or just share some ideas, doing it either physically or online, in small groups or large, as leader, or minor contributor. You will learn from these interactions.
* 6. __It's OK to copy stuff (to give you an idea)__ - it's not cheating, as long as you give appropriate credit, and you add something to it. And remember that it's a two-way street, where you need to be willing for other people to be building on your work, too.
* 7. __Keep your ideas in a sketchbook__ - documenting your ideas, process, projects, will help you to share with others, get feedback on your work, remember and generate new ideas in the future.
* 8. __Build, take apart, and rebuild__ - you shouldn't expect to get things right (or the way you want them) the first time. You often need to try again and again.
* 9 . __Lot's of things can go wrong; stick with it__ - when stuck, you need to be persistent and determined, but also learn strategies for getting unstuck. (and you need to know when to take a break, and come back later, often with new ideas, and a fresh approach).
* 10. __Create your own learning tips__ - learning strategies from others is very useful, but sometimes it is useful to come up with your own learning strategies and techniques. Pay attention to how you learn and what works for you. And don't be afraid to share these with others :)
!!! Ten Tips for Parents and Teachers
This section is organized around the five components of the Creative Learning Spiral: imagine, create, play, share, and reflect. The following strategies should help children imagine what they want to do, create projects through playing with tools and materials, share ideas and creations with others, and reflect on their experiences.
* 1. IMAGINE: Show examples to spark ideas
** Suggest that they insert their own voice or add their own personal touch. What might they do differently? How can they add their own style, connect to their own interests? How can they make it their own?
* 2. IMAGINE: Encourage messing around
** Most people assume that imagination takes place in the head, but the hands are just as important. To help children generate ideas for projects, we often encourage them to start messing around with materials.
* 3. CREATE: Provide a wide variety of materials
** To engage children in creative activities, make sure they have access to a broad diversity of materials for drawing, building, and crafting. New technologies, like robotics kits and 3-D printers, can expand the range of what children create, but don’t overlook traditional materials. The greater the diversity of materials, the greater the opportunity for creative projects.
* 4. CREATE: Embrace all types of making
** Different children are interested in different types of making. Children can learn about the creative design process through a variety of activities. Help children find the type of making that resonates for them. Even better: Encourage children to engage in multiple types of making. That way, they’ll get an even deeper understanding of the creative design process.
* 5. PLAY: Emphasize process, not product
** Many of the best learning experiences happen when people are actively engaged in making things. But that doesn’t mean we should put all our attention on the things that are made. Even more important is the process through which things are made. As children work on projects, highlight the process, not just the final product. Ask children about their strategies and their sources of inspiration. Encourage experimentation by honoring failed experiments as much as successful ones. Allocate times for children to share the intermediate stages of their projects and discuss what they plan to do next and why.
* 6. PLAY: Extend time for projects
** It takes time for children to work on creative projects, especially if they’re constantly tinkering, experimenting, and exploring new ideas (as we hope they will). Trying to squeeze projects into the constraints of a standard 50-minute school period—or even a few 50-minute periods over the course of a week—undermines the whole idea of working on projects. It discourages risk taking and experimentation, and it puts a priority on efficiently getting to the “right” answer within the allotted time. For an incremental change, schedule double periods for projects.
* 7. SHARE: Play the role of matchmaker
** Many children want to share ideas and collaborate on projects, but they’re not sure how. You can play the role of matchmaker, helping children find others to work with, whether in the physical world or the online world. You can bring together members with similar interests and/or bring together members with complementary interests.
* 8. SHARE: Get involved as a collaborator
** Parents and mentors sometimes get too involved in children’s creative projects, telling children what to do or grabbing the keyboard to show them how to fix a problem. Other parents and mentors don't get involved at all. There is a sweet spot in between, where adults and children form true collaborations on projects. When both sides are committed to working together, everyone has a lot to gain. Parents and children will have new respect for one another’s abilities, and relationships will strengthen.
* 9. REFLECT: Ask (authentic) questions
** It’s great for children to immerse themselves in projects, but it’s also important for them to step back to reflect on what’s happening. You can encourage children to reflect by asking them questions about their projects. I often start by asking: “How did you come up with the idea for this project?” It’s an authentic question: I really want to know! The question prompts them to reflect on what motivated and inspired them. Another of my favorite questions: “What’s been most surprising to you?” This question pushes them away from just describing the project and toward reflecting on their experience. If something goes wrong with a project, I’ll often ask: “What did you want it to do?” In describing what they were trying to do, they often recognize where they went wrong, without any further input from me.
* 10. REFLECT: Share your own reflections
** Most parents and teachers are reluctant to talk with children about their own thinking processes. Perhaps they don’t want to expose that they’re sometimes confused or unsure in their thinking. But talking with children about your own thinking process is the best gift you could give them. It’s important for children to know that thinking is hard work for everyone—for adults as well as children. And it’s useful for children to hear your strategies for working on projects and thinking through problems. By hearing your reflections, children will be more open to reflecting on their own thinking, and they’ll have a better model of how to do it. Imagine the children in your life as creative thinking apprentices; you’re helping them learn to become creative thinkers by demonstrating and discussing how you do it.
!!! Ten Tips for Designers and Developers
For people designing and developing new technologies and activities for learners:
* 1. __Design for designers__ - aim to enable the learners to design, create, express themselves.
* 2. __Support low floors and high ceilings__ - learners should be able to grow with their tools.
* 3. __Widen the walls__ - allow for many different learning and growing pathways, from the low floor to the high ceiling.
* 4. __Connect with both interests and ideas__ - connection with learner interests will engage them and motivate them to experiment, explore, and learn. Connection with new and powerful ideas will be useful for their entire lives.
* 5. __ Prioritize simplicity__ - don't fall for "feature creep". Prefer smaller, lighter, cheaper, simpler.
* 6. __Understand (deeply) the people you are designing for__ - study and interact with your users and observe what they are doing and how.
* 7. __Invent things that you want to use yourself__ - your designs are going to be much better if you create something you enjoy using.
* 8. __Put together a small interdisciplinary design team__ - designing playful learning technologies and environments requires expertise in multiple areas.
* 9. __Control the design, but leverage the crowd__ - to produce a coherent, consistent, integrated design, it is important to have a small team that controls and coordinates design decision and process. But it is valuable to get contributions and feedback from a larger community.
* 10. __Iterate, iterate -- then iterate again__ - things rarely come out right the first time. Developing actual prototypes is invaluable. They enable you to play and discuss them, but also have users play and provide feedback and observational data.
Resnick concludes:
>When I think about the transition to a Creative Society, I see myself as a short-term pessimist and a long-term optimist. I’m a short-term pessimist because I know how difficult it is to break down structural barriers and to shift people’s mindsets. These types of changes typically don’t happen overnight.
>At the same time, I’m a long-term optimist. There are long-term trends that will strengthen the case for Lifelong Kindergarten. As the pace of change continues to accelerate, the need for creative thinking will become more apparent. Over time, more and more people will come to understand the critical importance of helping children develop their creative capacities, and a new consensus on the goals of education will emerge.
----
^^1^^ The title is inspired by Robert Fulghum's (1986) title of his best-selling book //All I Really Need to Know I Learned in Kindergarten//, which focused on what children learn in kindergarten, and why those lessons remain important for the rest of their lives. Resnick's paper focuses on how children learn in kindergarten, and why kindergarten-style learning serves as a useful model for learners of all ages.
In the Principles of Computer Science (PCS) course I had developed and now teach for the second year, we have somewhat of a running joke about the "compactness and effectiveness of expressing oneself", which the students ended up calling being "concise", pronounced kontsiss (German roots?).
The students are taking the notion of being 'kontsiss' (and sometimes 'pretsiss' :) in various directions, one of them (naturally) is the brevity of programs. This is an old and persistent theme in CS. As [[they say|http://esolangs.org/wiki/Esoteric_programming_language]]:
>Many esoteric languages are designed to be as short as possible. These languages are known as "Golfing languages", and frequently used for "[[Code golf|https://en.wikipedia.org/wiki/Code_golf]]", a competition to solve programming tasks in as few characters or bytes as possible. Examples include ~CJam, [[Pyth|https://pyth.readthedocs.io/en/latest/]], and ~GolfScript, as well as many others.
These, sometimes very jovial^^1^^, discussions in class are not only enjoyable, but they also expand the students' horizons, because we get to touch on important topics and principles like programming style, readability, clarity, resource usage, effectiveness vs. efficiency, elegance (and yes, beauty), expressiveness, and, of course, preciseness/conciseness.
In the discussions about code brevity, the students (understandably) bring up the desire to write code where the variables are very short (as in 1 to 3 letters long), function names are cryptic and/or cute, and so on. Besides the obvious downsides in terms of readability/clarity, one has to be careful about taking brevity to the extreme:
In the [[Esoteric Languages wiki (esolangs)|http://esolangs.org/wiki/]], they define a [[Turing tarpit|http://esolangs.org/wiki/Turing_tarpit]] as
>a language that aims for Turing-completeness in an arbitrarily small number of linguistic elements - ideally, as few as possible.
The wiki entry doesn't fail to mention:
>The term "Turing tarpit" itself comes from the 1982 paper "[[Epigrams on Programming|http://thecorememory.com/Epigrams_on_Programming.pdf]]" by [[Alan Perlis|http://en.wikipedia.org/wiki/Alan_Perlis]] (a "[[CS Sage|https://en.wikipedia.org/wiki/List_of_computer_scientists]]"):
>>Beware of the Turing tar-pit in which everything is possible but nothing of interest is easy.
These words of wisdom from Perlis (in 1982) are very relevant even today, when you look at [[some of the "enterprises" people have undertaken|http://timeblimp.com/?page_id=2540]] designing new esoteric programming languages.
In the context of minimalist/golfing but Turing-complete languages it may be worth mentioning [[Pyth|https://pyth.readthedocs.io/en/latest/]] (see the [[online execution shell/compiler|https://pyth.herokuapp.com/]]).
I say this because I still remember the APL course I had taken as an undergraduate at the Technion. It was so different ("esoteric") from anything else I had experienced before, but it definitely opened my mind to concepts like functional programming, expressive power, data structures, data dimensions, etc. (and not to mention typing skills on the [[APL keyboard|resources/APL keyboard.gif]]).
So, for example, it may be instructive to discuss with students the pros and cons of 2 versions of [[looping through a range of integers|http://pyth.readthedocs.io/en/latest/simple-programs.html]] using 2 different idioms and approaches in Pyth (see the [[documentation|http://pyth.readthedocs.io/en/latest/index.html]]):
{{{
================= Pyth ============================
FNrZhTN
================= equivalent Python compilation ===
for N in Prange(Z,head(T)):
Pprint("\n",N)
==================================================
}}}
compared to:
{{{
================= Pyth ============================
VhTN
================= equivalent Python compilation ===
for N in urange(head(T)):
Pprint("\n",N)
==================================================
}}}
Leading to a very concise (kontsiss :) version of finding the factorial of a number:
{{{
input: 5
================= Pyth ============================
K1FNr1hQ=K*KN;K
================= equivalent Python compilation ===
Q=copy(literal_eval(input()))
K=1
for N in Prange(1,head(Q)):
K=copy(times(K,N))
Pprint("\n",K)
==================================================
}}}
----
^^1^^ - The jolliness can sometimes spill into some "silly cases", like for example, (briefly) talking about the [[HQ9+|https://esolangs.org/wiki/HQ9+]] joke language. It's obviously a nonsense language, but its possible "redeeming value" may be that it could be used as an exercise for students to implement in a course's (real) programming language of choice.
Here are some highlights from a blog post titled [[Ethical Theory|http://reasonandmeaning.com/2013/12/24/ethical-theory/]] by [[John G. Messerly|http://reasonandmeaning.com/brief-bio/]]: * There are many theories that deny morality^^1^^: nihilism; determinism; skepticism; relativism; egoism; etc. In my view ethicists too easily dismiss these theories—they have philosophical merit. * Most ethical theories try to justify morality. Typically this justification has been supplied by: self-interest—theories deriving from Plato and Hobbes; sympathy—theories deriving from Hume and Mill; nature—theories deriving from Aristotle and Aquinas; or reason—theories deriving from Kant and Locke. * Some contemporary thinkers, Darwall and Gewirth come to mind, have tried to justify morality following Kant. [...] At most, I would argue, these theories show that morality is weakly rational, i.e., morality is not clearly irrational. But I don’t see how they can show me how another person’s interests give me a reason to do anything. * Few contemporary thinkers have advanced natural law theories in the tradition of Aristotle and Aquinas. Contemporary thinkers try to bridge the is/ought gap with an evolutionary ethics or moral psychology utilizing knowledge of human nature unavailable to ancient and medieval philosophers. * Theories deriving from considerations of sympathy are also promising. Mill’s utilitarianism was based on a “social feeling,” Hume thought sympathy the basis of morality, Darwin had an entire theory of moral sentiments, and the contemporary philosopher Kai Nielsen places great emphasis on the role of sympathy in morality. It is hard to imagine a justification of the moral life without a role for sympathy. *Theories deriving from self-interest are promising, and contemporary contract and game theorists, particularly Gauthier, have gone a long way toward sustaining and revitalizing the Hobbesian project. Nonetheless, their results are inconclusive and it is not clear that this approach can resolve the compliance problem. However, combining a contract approach with considerations of our evolutionary nature and ingrained or acquired human sympathies may have more promise. *Finally, there are ethical theories associated with religious and metaphysical views, but lack of agreement about these views precludes any hope of grounding morality in them. (Of course the same may be said about one or another of our moral theories—that they all suppose some metaphysic and that the dispute about ethics depends on resolving metaphysical issues first.) Messerly ties this discussion to the [[Prisoner's Dilemma|Summary of the Prisoner’s Dilemma]]: * Let’s begin with the prisoner’s dilemma (PD). It is easy to see that self-interest demands defection, a supposedly non-moral move, in a one-time PD. So here self-interest and ordinary morality conflict. The fact that both parties do better through mutual cooperation somewhat ameliorates this conclusion, but does not change the fact that it is better for one to not comply no matter what the other does. * The situation changes when the PD is iterated, since tit-for-tat (TFT) has been shown to be a robust strategy. But recent work by Ken Binmore has challenged this assumption. (The “Folk-theorem” is also relevant here.) It is not that TFT is a bad strategy, but that real life is more complex than iterated ~PDs can model. There may be an infinite number of strategies which are robust, calling into question whether we can even determine what is in our self-interest. And if we don’t know what’s in our interest, how can self-interest ground morality? He brings in practical terms and considerations: * [Immoral actors] can’t determine what is in their self-interest. But can they make an educated guess? Not really. It is too difficult to know the repercussions of their acts and impossible to predict what adopting a disposition to behave will cost them in the long run. The complexity of the situation makes complete assessment impossible and reliable judgment unlikely, raising doubts about applying any moral theory to a complex world of interactions with other agents whose psychologies, motives, disposition and intents are difficult to determine if not opaque. *Thus it is unlikely that self-interest can ground morality or immorality since self-interest can’t be determined with accuracy. So where to from here? In large part, I find myself agreeing with the contemporary philosopher Kai Nielsen^^2^^. * Nielsen maintains that whether the bad guys are happy or not depends on what kinds of persons they are; and I agree. Neither rationality nor happiness requires morality: we must simply decide for ourselves how we should act and what sort of persons we will strive to be or become. * This means that considerations of reason, happiness, and self-interest, in the absence of sympathy and a commitment to the moral life, cannot adjudicate [i.e., make a formal judgment or decision] between morality and self-interest. * While both Neilsen and myself find this situation somewhat depressing, we accept that we cannot get to morality with intellect alone. From an objective point of view, reason is impotent to determine our values and thus the moral life demands a non-rational, voluntary commitment. In other words, the moral life and the immoral one are Kantian antimonies, and the choice between them interfused with existential angst. In the end we simply choose … and hope. * Does it help to know that we can’t give good self-interested reasons to comply with the social contract? ** [...] if mutual cooperation becomes important enough, ethics may become a branch of applied engineering. We may have to engineer ourselves, removing tendencies adaptive for foragers, but suicidal for beings with technology. ** And maybe engineering ourselves won’t entail a loss of freedom, but instead free us from some residual effects of our evolution, from overt aggressions and other tendencies that are now anachronistic in a technological world. But whatever we choose to do, one thing is certain, we alone are the stewards of the future of life and mind on this small outpost in an infinite cosmos. We alone must decide where we want to go. Again, bringing practicality into the discussion about ethical behavior Messerly concludes: * Remember that none of the above implies that it is irrational to be moral, only that rationality alone can’t get us to morality. This isn’t to say there aren’t good reasons to be moral. There are. Immoralists might be punished and lose the benefits of cooperation; and moralists don’t have to be looking over their shoulder and may have more friends. All we have said is that we can’t show that the reasons to be moral outweigh the reasons to be immoral, if you benefit from and can get away with immorality. * And we have also suggested that it is becoming increasingly within our power to remake the world and ourselves in such a way that no one can benefit from or get away with immorality. While some will object that nightmarish scenarios will follow from our increasing control of immoral behavior, it is quite likely that we will all benefit from a world in which peaceful living can be secured by the application of our knowledge. * Ironically, our inability to convincingly answer the why should I be moral question in theory, will lead to our answering it in practice. In short, there never have been completely convincing reasons to be moral, evidenced by the barbarism of human history, but, desperately in need of morality for our survival and flourishing, we will freely choose to transform ourselves by all means at our disposal. * In retrospect, biology and evolutionary stable strategies imposed early moral constraints, philosophical and religious education furthered the project, governments provided the muscle that conscience lacked, and now it is up to us to continue the project so that immorality doesn’t kill us. So we will be the ones who ultimately create the answer to the why be moral question. ---- ^^1^^ - Morality defined as a system demanding that persons express care, concern, and interest in others; exemplified by moral rules such as: “don’t kill, lie, cheat, or steal;” “help others;” etc. ^^2^^ - Nielsen, Kai. “Why Should I Be Moral?—Revisited” American Philosophical Quarterly 21, January 1984.
Bernie Siegel, M.D., in his book //Love, Medicine & Miracles// writes about //Becoming Exceptional// (chapter 8): > Psychologist Al Siebert became interested in the personalities of survivors when he joined the paratroopers just after college in 1953. >[...] He has found that one of their most prominent characteristics is a complexity of character, a union of many opposites that he has termed biphasic traits. They are both serious //and// playful, tough //and// gentle, logical //and// intuitive, hard-working //and// lazy, shy //and// aggressive, introspective //and// outgoing, and so forth. They are paradoxical people who don't fit neatly into the usual psychological categories. This makes them more flexible than most people, with a wider array of resources to draw from. >Siebert wondered how the survivor personality keeps from being immobilized by its contradictions. [... and building on concepts of Ruth Benedict and Abraham Maslow he] found that survivors have a hierarchy of needs and that, unlike most people, they pursue //all// of them. Beginning with the most basic, these needs are: survival, safety, acceptance by others, self-esteem, and self-actualization. One of the main needs that distinguished survivors from others, however, went beyond self-actualization: a need for synergy. Siebert defines the need for synergy as the need to have things work well for oneself //and// for others. >Survivors, then, act not only from self-interest, but also from the interest of others, even in the most stressful situations. They clean up messes and make things safer or more efficient. In short, they give of themselves, leaving the world better than they found it. Their relaxed awareness and the confidence that it brings allows them to save their energies for the really important things. When things are going well, they let well enough alone, leaving themselves free for curiousity about about new developments or potential problems. They may seem uninvolved at times, but they are "foul-weather friends." They show up when there's trouble.
In an [[interview of Daniel Kahneman|https://www.cfr.org/event/conversation-daniel-kahneman]] (an Economics Nobel Laureate (with Amos Tverski)), he made a few interesting observations about both human and artificial intelligence (the following is "somewhat heavily edited", since the source is the conversational material from the interview): !!! On his book [["Thinking Fast and Slow"|https://www.nytimes.com/2011/11/27/books/review/thinking-fast-and-slow-by-daniel-kahneman-book-review.html]] The book is an exploration of how the human mind works and how intuitive thinking, which is called “System 1,” interacts with deliberative thinking, “System 2.” And the conclusion is that System 1 is dominant and influential—more than we realize. The claim in the book is that what we are conscious of, we are conscious of our conscious thoughts. We are conscious of our deliberations. But most of what happens in our mind happens silently, i.e., the most important things that happen in our mind happen silently. We’re just aware of the result. We’re not aware of the process. And so the process that we’re aware of tend to be deliberate and sequential, but the associative networks that lies behind it and that brings ideas forward into consciousness, we’re really not aware of it. So we live with System 2. We’re mostly aware of it. And System 1, which does most of the work, is not recognized. But because we’re aware of the deliberative thinking, we tend to think our decisions are more deliberative than they really are. !!! On Artificial Intelligence and Machine Learning The question is whether this human process where the brain works and the interaction between the intuitive and the deliberative happens naturally can ever be replicated by algorithms. The answer is almost certainly yes. This is a computing device that we have. It won’t be replicated exactly. It shouldn’t be replicated exactly. But that you can train an artificial intelligence to develop powerful intuitions in a complex domain, this we know. For example, the ~AlphaGo software learning to play GO, beating the world champion, and then, by playing against itself and training for millions of more games, is far exceeding human skill and capabilities. The kinds of progress that you can make with machine learning is great. Go is a good example because it's an intuitive game. It’s a game that typically people cannot really explain why they feel a move is strong or not. But Go experts observed ~AlphaGo and realized that moves that the program made were extremely strong moves and completely novel ones. Will we algorithmically integrate the intuitive and deliberative systems better than the human brain does? One of the things that we'll be able to do is develop programs to explain their decisions in System 2 (conscious, deliberative) terms. So it’s going to be separate because what generates a solution is the deep learning. But it will automatically look at the big data and develop a story that we can grasp. It looks very likely that we’ll develop programs to tell stories about those decisions so that we can understand them in terms of reasoned arguments. !!!On the difficulty (and automatic perceptual and conceptual "lock-in") of being able to see and deal with alternatives (or why is it so hard to come up with alternative stories?): This is really a characteristic of the perceptual system, that when we perceive things we make a choice. And frequently, when stimuli are ambiguous, we can see it this way or that way. And a remarkable and simple example is the [[Necker cube|https://en.wikipedia.org/wiki/Necker_cube]]. It’s flat on the page, but it appears three-dimensional, and it "flips". If you stare at it long enough, there are two three-dimensional solutions that you see, and they "flip" automatically. There's nothing voluntary about it. And it flips all at once, and you only see one interpretation—you can’t see them both at the same time. You know that there are two, but you see only one. And what happens is a process where once a solution gets adopted, it suppresses others. And this mechanism of a single solution coming up and suppressing alternatives, that occurs in perception and it occurs in cognition. So when we have a story, it suppresses alternatives.
In his essay [[The Hedgehog and the Fox: An Essay on Tolstoy’s View of History|https://www.blogs.hss.ed.ac.uk/crag/files/2016/06/the_hedgehog_and_the_fox-berlin.pdf]] Isaiah Berlin writes: >There is a line among the fragments of the Greek poet Archilochus which says: ‘The fox knows many things, but the hedgehog knows one big thing.’ > >Scholars have differed about the correct interpretation of these dark words, which may mean no more than that the fox, for all his cunning, is defeated by the hedgehog’s one defense. But, taken figuratively, the words can be made to yield a sense in which they mark one of the deepest differences which divide writers and thinkers, and, it may be, human beings in general. > >For there exists a great chasm between those, on one side,who relate everything to a single central vision, one system, less or more coherent or articulate, in terms of which they understand,think and feel–a single, universal, organising principle in terms of which alone all that they are and say has significance–and, on the other side, those who pursue many ends, often unrelated and even contradictory, connected, if at all, only in some de facto way, for some psychological or physiological cause, related to no moral or aesthetic principle. > >These last lead lives, perform acts and entertain ideas that are centrifugal rather than centripetal; their thought is scattered or diffused, moving on many levels, seizing upon the essence of a vast variety of experiences and objects for what they are in themselves, without, consciously or unconsciously, seeking to fit them into, or exclude them from, any one unchanging, all-embracing, sometimes self-contradictory and incomplete, at times fanatical, unitary inner vision. > >The first kind of intellectual and artistic personality belongs to the hedgehogs, the second to the foxes; and without insisting on a rigid classification, we may, without too much fear of contradiction, say that, in this sense, Dante belongs to the first category, Shakespeare to the second; Plato, Lucretius, Pascal, Hegel, Dostoevsky, Nietzsche, Ibsen, Proust are, in varying degrees, hedgehogs; Herodotus, Aristotle,Montaigne, Erasmus, Molie`re, Goethe, Pushkin, Balzac, Joyce are foxes. > >Of course, like all over-simple classifications of this type, the dichotomy becomes, if pressed, artificial, scholastic and ultimately absurd. But if it is not an aid to serious criticism, neither should it be rejected as being merely superficial or frivolous; like all distinctions which embody any degree of truth, it offers a point of view from which to look and compare, a starting-point for genuine investigation. This, I think, inspired Stephen Jay Gould to write his book [["The Hedgehog, the Fox, and the Magister’s Pox"|On "The Hedgehog, the Fox, and the Magister’s Pox" by Stephen Jay Gould]].
In an article titled [[The Chess Master and the Computer|http://www.nybooks.com/articles/2010/02/11/the-chess-master-and-the-computer/]] in the //New York Review of Books//^^1^^, Chess Grand Master [[Garry Kasparov]] (of Deep Blue infamy :) tells the following story, and makes the following observations: >As for how many moves ahead a grandmaster sees, [...] the answer attributed to the great Cuban world champion [[José Raúl Capablanca|https://en.wikipedia.org/wiki/Jos%C3%A9_Ra%C3%BAl_Capablanca]], among others [was]: “Just one, the best one.” >This answer is as good or bad as any other, a pithy way of disposing with an attempt by an outsider to ask something insightful and failing to do so. It’s the equivalent of asking [[Lance Armstrong|https://en.wikipedia.org/wiki/Lance_Armstrong]] (of the Tour de France cheating infamy) how many times he shifts gears during the Tour de France. > >The only real answer, “It depends on the position and how much time I have,” is unsatisfying. > >[...] >Capablanca’s sarcasm aside, correctly evaluating a small handful of moves is far more important in human chess, and human decision-making in general, than the systematically deeper and deeper search for better moves—the number of moves “seen ahead”—that computers rely on. > >[...] >[Chess] demands high performance from so many of the brain’s functions. Where so many of these investigations fail on a practical level is by not recognizing the importance of the process of learning and playing chess. The ability to work hard for days on end without losing focus is a talent. The ability to keep absorbing new information after many hours of study is a talent. Programming yourself by analyzing your decision-making outcomes and processes can improve results much the way that a smarter chess algorithm will play better than another running on the same computer. We might not be able to change our hardware, but we can definitely upgrade our software. > >[...] >Playing better chess was a problem they ["the finest minds of the twentieth century"] wanted to solve, yes, and it has been solved. But there were other goals as well: to develop a program that played chess by thinking like a human, perhaps even by learning the game as a human does. Surely this would be a far more fruitful avenue of investigation than creating, as we are doing, ever-faster algorithms to run on ever-faster hardware. Reminds me of [[comments Alan Kay made|It's about Big Meaning, not Big Data.]]: It should not be about Big Data, it should be about Big Meaning. He basically said we are tackling the wrong (but easier?) problems in Computation and Computer Science by throwing more hardware at automation problems. In Kasparov's words: >This is our last chess metaphor, then—a metaphor for how we have discarded innovation and creativity in exchange for a steady supply of marketable products. The dreams of creating an artificial intelligence that would engage in an ancient game symbolic of human thought have been abandoned. Instead, every year we have new chess programs, and new versions of old ones, that are all based on the same basic programming concepts for picking a move by searching through millions of possibilities that were developed in the 1960s and 1970s. >Like so much else in our technology-rich and innovation-poor modern world, chess computing has fallen prey to incrementalism and the demands of the market. Brute-force programs play the best chess, so why bother with anything else? Why waste time and money experimenting with new and innovative ideas when we already know what works? Such thinking should horrify anyone worthy of the name of scientist, but it seems, tragically, to be the norm. Our best minds have gone into financial engineering instead of real engineering, with catastrophic results for both sectors. ---- ^^1^^ compare to [[The end of an era, the beginning of another? HAL, Deep Blue and Kasparov|The end of an era, the beginning of another? HAL, Deep Blue and Kasparov]]
I came across [[a short article about book indexing|resources/on_indexing_books.pdf]], and it opened for me a little window into the world of professional indexing and indexers (I assume they have labor unions, conferences, etc.). It's written by a professional indexer, admiring the amateurish indexing work done by an author I very much admire (Douglas Hofstadter), and provides an interesting glimpse into what was involved in Hofstadter indexing his book //Le ton beau de Marot: in praise of the music of language//. It puts in words what I felt when I (very rarely :-( came across a "good index" at the back of a book: that a good index is a kind of a "mind-map" giving the reader a "navigational aid" by mapping some of the author's mind/concepts/thoughts (which are not reflected in the actual text; kind of at a "meta-level") in a different way (compared to the table of contents, list of illustrations, the linear progression of the book/text itself, etc.). It turns out that the index provides new insights not only to the reader, but also to the writer, as Hofstadter indicates: >"This tiny-print behemoth ... was a labor of love that took me a full month of fifteen-hour days to carry off.' Creating the index provided him with the sort of insights acquired in the course of this work which usually come too late to serve any useful purpose. 'Doing this index,' Hofstadter continues, 'painful though it was, afforded me one last pass back through the text, tying things together for a final time, saying goodbye to a work created out of love, and with love, for words, ideas, people... For instance, there was one giant index entry that came entirely out of the blue, catching me very much off guard. That was the entry for "conflation". F m not even sure I'm using the word in a standard way, in fact. What it means to me is "taking one thing for another", as in the sentence, "Don't conflate the meanings of 'conflate' and 'confound', please!" I noticed one instance of conflation (in this sense, at least), indexed it, then saw another, and pretty soon it dawned on me that this theme was omnipresent in my book, and so I spent several hours just searching for instances of conflation not the word, mind you, but the concept. It was a revelation to me how pervasive it was, even though the word itself occurred only a handful of time. But indexing (like many other activities) can be taken too far, as demonstrated by another professional indexer (William S. Heckscher): >'I have indicated that for me there should be a carefully attuned balance between Index on one side and Text, Notes, Illustrations, on the other ... Ideally, then, a good Index should be more than merely a taciturn sign-post erected after all the rest has been done and is immutably crystallized.... I prefer the Index which has a life of its own, which may pride itself on being the child of imagination, and which should enable us to spend a peaceful evening in bed, reading such an Index, as if we were reading a good novel.' Or in the case of Hofstadter's indexing obsession, ending in (potentially endless) __self-referenciality__ [[(a-la strange loopiness?)|http://en.wikipedia.org/wiki/I_Am_a_Strange_Loop]]: >The long entry for conflation in the index (without quotation marks as printed) is followed by a brief one for "conflation" (in double quotes): >>"conflation": DRH's personal usage, 598; lengthy index entry for, 598. 613 >This entry, therefore, refers both to the endnote quoted above, and to the entry which immediately precedes it in the index. Self-referentiality can surely go no further. Even __self-referentiality__ can be taken too far: >I don't know whether anyone told Douglas Hofstadter about the persistent myth that every index must contain a joke; his index contains many. But here is a particularly playful example which may annoy many people as much as it delights me. Under 'index' in the index, a subheading reads 'typo in, 631' (the index extends over pages 599 to 632). On page 631 we find a further index entry, 'typo in index, 633'. There is, of course, no page 633.
In an excellent book titled [["When Einstein Walked with Gödel -- Excursions to the Edge of Thought"|https://www.nytimes.com/2018/05/15/books/review/review-when-einstein-walked-with-godel-jim-holt.html]]^^1^^, Jim Holt has a chapter about Georg Cantor and his work on infinities (an infinite number of types of infinity). Holt describes Galileo's insight (and puzzlement, or even bewilderment) into the strange nature of infinity. Galileo reasoned that the set of all whole numbers (i.e., 1, 2, 3, 4, ...) is infinitely large: there is no end to them. Looking at the set of just the squares of the whole numbers (i.e., 1, 4, 9, 16, ...) one gets the sense that their number is smaller than the number of whole numbers, since they are a subset of the wholes. But one can simply pair up or map every whole number with every square (i.e., 1 with 1, 2 with 4, 3 with 9, 4 with 16, ...), and vice versa. And the inevitable conclusion is that these two sets have the same size. So, it looks like what seems to be a subset of a set (i.e., the squares) actually has the same size of the set (i.e., the wholes). Holt (following Cantor) describes/exemplifies infinity in a short and elegant way: an infinite set is a set that is the same size as some of its parts. In other words, an infinite set is a set that can lose some of its members without being diminished. In his work on infinities, Cantor also arrived at a powerful principle that enabled him to further develop his theories, namely that there are always more //sets// of things than things. In other words, given a number of things, you can arrange those things in more ways than the number of things. I think (and I'm not the only one :) that this combinatorial fact/power lies at the heart of human creativity. As [[Maria Popova writes|About creativity and innovation]] in [[her blog|https://www.brainpickings.org/2011/08/01/networked-knowledge-combinatorial-creativity/]]: >creativity is combinatorial, that nothing is entirely original, that everything builds on what came before, and that we create by taking existing pieces of inspiration, knowledge, skill and insight that we gather over the course of our lives and recombining them into incredible new creations. So, combining (ha!) the two ideas, it seems that the number of (creative) combinations is always larger than the number of the building blocks, which bodes well for creativity, since if the number of building blocks is very large (tends to infinity?), than the number of creative combination is even larger (tending to (a larger?) infinity?). ---- ^^1^^ - searchable spelling: Gödel, Godel, Goedel
In his book On Intelligence (published in 2004), Jeff Hawkins defines intelligence in a different way from one of the traditional/classic ones, formulated by Alan Turing (the [[Turing Test|https://plato.stanford.edu/entries/turing-test/]]).
A human doesn't need to "do" anything to understand a story. I can read a story quietly, and although I have no overt behavior my understanding and comprehension are clear, at least to me. You, on the other hand, cannot tell from my quiet behavior whether I understand the story or not, or even if I know the language the story is written in. You might later ask me questions to see if I did, but my understanding occurred when I read the story, not just when I answer your questions.
A thesis of this book is that understanding cannot be measured by external behavior; as we'll see in the coming chapters, it is instead an internal metric of how the brain remembers things and uses its memories to make predictions.
<<list-links "[tag{!!title}]">>
I have just finished an interesting book //The Accidental Universe - The World You Thought You Knew// by Alan Lightman, where he calls the world we live in "[[The Disembodied Universe|More on unthinkable thoughts]]", and laments the impact of science and technology on our worldview. As a physicist, he loves and appreciates all the positive things that humanity and individuals have gained from science and technology, but he also points out some of the negatives that come with that. He says: >It is an irony to me that the same science and technology that have brought us closer to nature by revealing these invisible worlds have also separated us from nature and from ourselves. Much of our contact with the world today is not an immediate, direct experience, but is instead mediated by various artificial devices such as television, cell phones, iPads, chat rooms, and mind-altering drugs. and gives a few examples: >Speaking on the phone while walking through a nature preserve represents a certain level of disconnection from one's immediate surroundings, but sending test messages is an even greater abstraction. And text messaging is becoming the preferred means of communication by a large segment of the population. A personal experience of this happened this today -- a Sunday, early in the morning. My wife got a text message on her cellphone. It turned out to be a friend of hers, apologizing about something she had said the day before when both of them met. My wife immediately texted back, saying (actually, writing) that there was no need to apologize, since she was not hurt at all. To which the friend replied that she thought about it all of last night. At this point in the back-and-forth texting, my wife said to me: "I need to talk to her. There is nothing better than a face-to-face conversation". And proceeded to pick up the phone and called her (my father would have said (in Yiddish): a shein ding (a 'nice' thing): "face-to-face" oif them telephon :-| ). More like ear-to-ear... Other examples of this distancing are: >When young people go to parks, they are often so busy clicking photos with their iPhones and emailing the pictures to their Facebook pages that they do not remember to stop for a moment and contemplate the scene with their own eyes. The most unfortunate aspect of this new behavior is that more and more people, and especially young people, are taking such mediated experiences as "natural", as the norm. He describes scenes from the book //Alone Together// by Sherry Turkle (MIT psychologist and social scientist), where >she documents the way in which email and cell phones have created emotional dislocations and superficial but expedient ways to deal with the frantically paced world of the twenty first century. [... someone describes how they] "use email to make appointments to see friends, but I am so busy that I'm often making an appointment one or two months in the future. After we set things by email, we do not call. I don't call. They don't call. What do I feel? I feel I have 'taken care of that person.' " And Lightman continues: >Using technology, we have redefined ourselves in such a way that our immediate surroundings and relationships, our immediate sensory perceptions of the world, are much diminished in relevance. We have trained ourselves not to be present. We have extended our bodies, created enhanced selves that might be called our "techno-selves". Our techno-selves are both bigger and smaller than our former selves. Bigger in that we have tremendous powers to communicate with the invisible world. Smaller in that we have sacrificed some of our contact and experience with the visible, immediate world. He correctly points out that new technologies significantly impacted humanity in the past, and people in the past were concerned and sometimes horrified by the potential and risks: the response to the industrial revolution in the eighteenth century; the fear of humans causing the vanishing of natural landscapes in the nineteenth century; the strong emotions to the roll out of the railroads in the US (e.g., Henry David Thoreau and the Transcendentalists saying: "we do not ride the railroad. It rides us."); skype calls to friends and family instead of meeting face-to-face; our preference to look at animals and nature through high resolution lenses with impressive zooming, instead of looking at them with the naked eye; dinners, where everyone at the table has their cell phones next to their plates, regularly being checked for new messages; and so on. Another point Lightman makes, but doesn't develop, is that without (or before the development of) modern science and technology, we are a bit like the Flatlander from [[the book Flatland|http://www.geom.uiuc.edu/~banchoff/Flatland/]] by Edwin A. Abbott, a strictly 2D world where the creatures in it have no notion nor perception of 3D (or the third dimension). Abbott tells a story of these strictly 2 dimensional creatures, which one day are being visited by someone from the third dimension. This comparison is a thought-provoking one. Being aware of the 3^^rd^^ dimension and reading Flatland, definitely makes you feel that the Flatlanders are missing out on a lot of reality. Looking at our sensory reality without the augmentation of science and technology has to lead to the same conclusion: there is more to reality than what we directly perceive, and used wisely (and that's the key!), science and technology can make our universe so much richer. It can be a quantum leap; a kick-up into higher dimensions :) Lightman concludes the book by writing: >Most of us will adapt to this new way of living [...] It will be the natural and normal way of being in the world. But here and there, small pockets of people will rebel and establish small communes, where the newer technologies are left at the front gate -- in the same way that some people today still send handwritten letters and take long walks without their cell phones. In such enclaves, people will feel that they have preserved something of value, that they are living a more immediate and authentic life, that they are more connected with themselves and their surroundings. And that will be partly true. Yet they will be also disconnected from the larger world just outside of their gate, invisible in their own way. I'm sure this will happen, as similar things happened in the past throughout human evolution. Wisdom, as well as human resiliency, one hopes, will lead us through these changes, to arrive at a balance and a "sane" way of living. Part of successfully navigating through this is remembering that progress is rarely "smooth"; the ups and downs, overshooting and undershooting, actions and reactions are the natural way of progress.
!!! On Luck In an interesting article in The Atlantic titled "[[Why Luck Matters More Than You Might Think|http://www.theatlantic.com/magazine/archive/2016/05/why-luck-matters-more-than-you-might-think/476394/]]", Robert Frank brings up some good points: * many of us seem uncomfortable with the possibility that personal success might depend to any significant extent on chance. As E. B. White once wrote, “Luck is not something you can mention in the presence of self-made men.” Wealthy people overwhelmingly attribute their own success to hard work rather than to factors like luck or being in the right place at the right time. * __The bad news__: because a growing body of evidence suggests that seeing ourselves as self-made - - rather than as talented, hardworking, and lucky - - leads us to be less generous and public-spirited. It may even make the lucky less likely to support the conditions (such as high-quality public infrastructure and education) that made their own success possible. ** in other words, if you are successful, you tend to attribute it to your hard work, talent, etc., which in turn makes you less charitable, generous, and supportive of conditions to help others be successful. * __The good news__: when people are prompted to reflect on their good fortune, they become much more willing to contribute to the common good. ** in other words, if you are somehow made to reflect on your success and consider factors outside of your control, (e.g., good fortune/luck), you tend to be more charitable, generous, and supportive of conditions to help others be successful. * Why we may see success as inevitable is the "availability heuristic". Using this cognitive shortcut, we tend to estimate the likelihood of an event or outcome based on how readily we can recall similar instances. Successful careers, of course, result from many factors, including hard work, talent, and chance. Some of those factors (in our control or nature) recur often, making them easy to recall. But others (not in our control) happen sporadically and therefore get short shrift when we construct our life stories. * That we tend to overestimate our own responsibility for our successes is not to say that we shouldn’t take pride in them. Pride is a powerful motivator; moreover, a tendency to overlook luck’s importance may be perversely adaptive, as it encourages us to persevere in the face of obstacles. * And yet failing to consider the role of chance has a dark side, too, making fortunate people less likely to pass on their good fortune. * Our personal narratives are biased in a second way: Events that work to our disadvantage are easier to recall than those that affect us positively. My friend Tom Gilovich invokes a metaphor involving headwinds and tailwinds to describe this asymmetry. ** When you’re running or bicycling into the wind, you’re very aware of it. You just can’t wait till the course turns around and you’ve got the wind at your back. When that happens, you feel great. But then you forget about it very quickly—you’re just not aware of the wind at your back. And that’s just a fundamental feature of how our minds, and how the world, works. We’re just going to be more aware of those barriers than of the things that boost us along. * In an unexpected twist, we may even find that recognizing our luck increases our good fortune. Social scientists have been studying gratitude intensively for almost two decades, and have found that it produces a remarkable array of physical, psychological, and social changes. ** psychologists have documented additional benefits of gratitude, such as reduced anxiety and diminished aggressive impulses. !!! On Grit In the same issue of The Atlantic, Jerry Useem has an article titled "[[Is Grit Overrated?|http://www.theatlantic.com/magazine/archive/2016/05/is-grit-overrated/476397/]]", with some interesting points, too: * grit - - perseverance plus the exclusive pursuit of a single passion - - is a severely underrated component of career success, and that grown-ups, too, need a better understanding of the nature and prevalence of setbacks. * Initially, Angela Duckworth, a psychology professor at the University of Pennsylvania, guessed that the answer had to do with short-term impulse control. But impulse control did not fully account for how long people persisted at something in the absence of positive feedback such as success. * What distinguished high performers, she found, was largely how they processed feelings of frustration, disappointment, or even boredom. Whereas others took these as signals to cut their losses and turn to some easier task, high performers did not - - as if they had been conditioned to believe that struggle was not a signal for alarm. * To Duckworth, here was an opening. If you could change people’s beliefs about how success happens, then you had a crack at changing their behavior - - delaying their quitting point a crucial modicum (i.e., a bit) or two. * But grit and the continued efforts and failures on the way to success are ugly, uncomfortable, messy. Successful people hide the messiness and show just the successful, polished end result. ** “If people knew how hard I had to work to gain my mastery, it would not seem so wonderful at all,” Michelangelo observed. Nietzsche concurred: “Wherever one can see the act of becoming one grows somewhat cool.” * Duckworth’s basic admonition, “Embrace challenge,” needs a qualifier: Do it in private. Grit may be essential. But it is not attractive. ** This can make for confusing career advice. “Try hard enough and you can do just about anything, as long as you don’t seem to be trying very hard” is not the stuff of school murals. * the prevalence of hidden practice among successful people is costly to society because it obscures the amount of failure that goes into success. It is a destructive negative cycle: ** If we routinely fool others, they routinely fool us. So when we experience messy frustration, we too readily believe that we don’t have the right stuff and give up. * So, one of the useful pieces of advice may be to not hide the messiness on the way to success (similar to the suggestion not to keep all the "failed research" in the drawer" because it has value. ** From an insight, educational and wisdom point of view: You should be courageous enough to hold your failure up to others and say, in effect, this is what success looks like. !!!! On Grit and Knowing When It's Worth It As in many cases in life, discernment is probably the wise way to success, happiness, and everything :) From [[Give Up|http://www.theatlantic.com/health/archive/2015/10/give-up/410485/]]: > “Right now, there’s an effort to push everyone to be more gritty,” said Gale Lucas, a researcher with the USC Institute for Creative Technologies, in a statement. “There’s no reason not to make people grittier, but it’s important to know when to quit and reevaluate rather than blindly push through.” > In general, willpower in the face of adversity is an asset. But as this study (and real life) illustrates, some things are just not worth achieving, no matter how gritty you are. Grit, then, is like any other gift—it’s worth evaluating whether you’re using it to help, rather than hurt, yourself.
In an essay titled [["Metaphors and Mental Models: The Key to Understanding"|http://investorfieldguide.com/metaphors-and-mental-models-the-key-to-understanding/]] [[Patrick O’Shaughnessy|http://investorfieldguide.com/about/]] is trying to explain consciousness, but first tries to clarify what an analog vs. metaphor is: >An analog is a model, but a model of a special kind. It is not like a scientific model, whose source may be anything at all and whose purpose is to aid as an hypothesis of explanation or understanding. Instead, an analog is at every point generated by the thing it is an analog of. A map is a good example. It is not a model in the scientific sense, not a hypothetical model like the Bohr atom to explain something unknown. Instead, it is constructed from something well known, if not completely known. Each region of a district of land is allotted a corresponding region on the map, though the materials of land and map are absolutely different and a large proportion of the features of the land have to be left out. And the relation between an analog map and its land is a metaphor. And on to consciousness: >Subjective conscious mind is an analog of what is called the real world. It is built up with a vocabulary or lexical field whose terms are all metaphors or analogs of behavior in the physical world. Its reality is of the same order as mathematics. [...] Now when we say mind-space is a metaphor of real space, it is the real ‘external’ world that is the metaphier^^1^^ [the tool/process/reference point used to explain something -- the metaphrand^^1^^ (thing to be explained)]. But if metaphor generates consciousness rather than simply describes it, what is the metaphrand [thing to be explained]? He continues by assuming (or believing, [[similarly to David Darling and Mario Livio|The relationship between the world out there and what's inside our mind]]) that "there is something out there" with certain characteristics, which we perceive (are conscious about): >The world is organized, highly organized, and the concrete metaphiers that are generating consciousness thus generate consciousness in an organized way. Hence the similarity of consciousness and the physical-behavioral world we are conscious of. And hence the structure of that world is echoed —though with certain differences—in the structure of consciousness. The analogy (ha!) of a map is helpful in understanding the above, and the following ideas: >A cardinal property of an analog is that the way it is generated is not the way it is used—obviously. The map-maker and map-user are doing two different things. For the map-maker, the metaphrand is the blank piece of paper on which he operates with the metaphier of the land he knows and has surveyed. But for the map-user, it is just the other way around. The land is unknown; it is the land that is the metaphrand, while the metaphier is the map which he is using, by which he understands the land. Notice the bi-directional roles and processes, which potentially can cause a "closed loop" (where the map user feeds back to the map maker, who modifies things and feeds it back to the user, and so on). And back to consciousness: >And so with consciousness. Consciousness is the metaphrand when it is being generated by the paraphrands [associations of/with the original metaphrand] of our verbal expressions. But the functioning of consciousness is, as it were, the return journey. Consciousness becomes the metaphier full of our past experience, constantly and selectively operating on such unknowns as future actions, decisions, and partly remembered pasts, on what we are and yet may be. And it is by the generated structure of consciousness that we then understand the world. And isn't it [[a "strange loop"|On the strange human loop]] we are (in)? ---- ^^1^^ - Terms used by [[Julian Jaynes|https://www.julianjaynes.org/about-julian-jaynes.php]] who is defining metaphor as something made up of two components: the thing to be described, which I shall call the metaphrand, and the thing or relation used to elucidate it, which I shall call the metaphier. A metaphor is always a known metaphier operating on a less known metaphrand.
In a book titled [["Moral Machines - Teaching Machines Right from Wrong"|https://www.researchgate.net/publication/257931212_Moral_Machines_Contradiction_in_Terms_or_Abdication_of_Human_Responsibility]], the authors Colin Allen and Wendell Wallach write that (ro)bot (physical robots and software agents) like driverless cars and trains, financial transactions and networks, lethal weapons systems, artificial pet, and home appliances, are becoming a reality, which will lead up to questions about Artificial Moral Agents. This is adding to [[the debates|https://nationalhumanitiescenter.org/on-the-human/2011/12/the-future-of-moral-machines/]] about the rewards and risks involved as a result of "Superintelligent AI and the Postbiological future" (see also [[Susan Schneider's philosophical discussion|http://schneiderwebsite.com/index.html]] of these issues). See also [[The AI Revolution: Our Immortality or Extinction|https://waitbutwhy.com/2015/01/artificial-intelligence-revolution-2.html]]. ''A few points from their book and [[the NYT article|https://opinionator.blogs.nytimes.com/2011/12/25/the-future-of-moral-machines/]]'': * The human-built environment increasingly is being populated by artificial agents, which combine limited forms of artificial intelligence with autonomous (in the sense of unsupervised) activity. The software controlling these autonomous systems is, to date, “ethically blind” in two ways. First, the decision-making capabilities of such systems do not involve any explicit representation of moral reasoning. Second, the sensory capacities of these systems are not tuned to ethically relevant features of the world. * There are big themes here: freedom of will, human spontaneity and creativity, and the role of reason in making good choices — not to mention the nature of morality itself. Fully human-level moral agency, and all the responsibilities that come with it, requires developments in artificial intelligence or artificial life that remain, for now, in the domain of science fiction. And yet… * Machines are increasingly operating with minimal human oversight in the same physical spaces as we do. * Whether we want them or not they will appear, probably sooner than later ** Why? It's all about power. ** Humans are moral agents, but are they always in reality? ** So who or what to fear more: humans or machines? * Implementation approaches: ** Philosophers approach to moral decision making: *** Top‐down: Use of rules, standards or theories to guide the design of a system's control architecture. ** Engineers approach: *** Bottom‐up: Rules are not explicitly defined, but the system learns about them through experience.
[[Richard Feynman once said|Richard Feynman on the beauty and simplicity of nature]]: >Perhaps a thing is simple if you can describe it fully in several different ways without immediately knowing that you are describing the same thing. which reminds me of something my father used to say: >If you really know mathematics and "deeply feel it", you fully understand that when you say that 3 * 4 = 12 (or 3 x 4 = 12), you also say that "3 goes/fits into 12 four times", and that "4 goes/fits into 12 three times", and that "a quarter of 12 gives you 3", and that "12 divided into three equal parts is 4". Sometimes, this "symmetry" or multi-facetness can be very "illuminating", since it may reveal something deep about reality, i.e., physics (or math), which is [[something that people like Bertrand Russell and Judea Pearl had observed and talked about|On The Art and Science of Cause and Effect - Judea Pearl]]. <html> <a href="https://trinket.io/python/d640d97144?outputOnly=true&runOption=run" target="new"><img src="resources/polygon laps 3 4.png" width="25%" height="25%" /></a> </html> I recently played with programming [["polygon laps"|https://trinket.io/python/bb7245123b]] (inspired by [[Dave Whyte|https://beesandbombs.tumblr.com/post/161295765794/polygon-laps]]) and realized another way in which this simple but deep understanding manifests itself. If you click on the image which leads to a Python-driven animation, you can see 2 dots tracing a triangle (3 sides) and a square (4 sides), in something like a polygon laps race. Running this for a while (at least 12 segments :) makes the statements above clear in a simple, visual way ... :) ---- for search purposes (and since I believe that this is the example my father used :), this can equally apply to exploring/understanding multiple facets of 2 x 3 (or 2 * 3, 2*3, 2x3 and so on)
In her book //The Left Hand of Darkness// (see the [[introduction to the book|Ursula K. Le Guin on Science Fiction, Writing, and the Truth]]), Ursula K. Le Guin writes a very insightful and personal description of what "love of one's country" means to a (humanoid) alien on Planet Winter. The alien is a citizen of one country (Karhide) on Planet Winter, and the narrator, an Envoy from another planet, is asking him: > You hate Orgoreyn [the other country on this planet], don't you? > [...] Hate Orgoreyn? No, how should I? How does one hate a country, or love one? Tibe [the "nationalistic 'prime minister' " of Karhide] talks about it; I lack the trick of it. I know people, I know towns, farms, hills and rivers and rocks, I know how the sun at sunset in autumn falls on the side of a certain plowland in the hills; but what is the sense of giving a boundary to all that, of giving it a name and ceasing to love where the name ceases to apply? What is love of one's country; is it hate of one's uncountry? Then it's not a good thing. Is it simply self-love? That's a good thing, but one mustn't make a virtue of it, or a profession. ... Insofar as I love life, I love the hills of the Domain of Estre [where I was born], but that sort of love does not have a boundary-line of hate. And beyond that, I am ignorant, I hope. > Ignorant, in the Handdara [a mystic/spiritual sect in Karhide] sense: to ignore the abstraction, to hold fast to the thing.
Pushpinder Singh and [[Marvin Minsky|https://en.wikipedia.org/wiki/Marvin_Minsky]] (of MIT; a "[[CS Sage|https://en.wikipedia.org/wiki/List_of_computer_scientists]]"; one of the Founding Fathers of Artificial Intelligence) wrote [[an article titled "Failure-Directed Reformulation"|http://dspace.mit.edu/bitstream/handle/1721.1/46197/40495901-MIT.pdf?sequence=2]], in which [[they say|https://www.researchgate.net/publication/2555137_Failure-Directed_Reformulation]]: >[In the] domain of ordinary, common-sense problem solving [, ...w]e study the heuristic method of reformulation, that is, of changing the representation of the problem. We are interested in reformulations that cause a substantial change in viewpoint, one that is likely to be different enough from the original viewpoint that we have a good chance of getting unstuck. We present a simple way of organizing representations so that reformulation can occur quickly if a dead-end is encountered while applying current method of solution. I recently came across a vivid example of reformulation helping to solve a common-sense problem. The problem is the famous "water jugs" problem, also demonstrated in the movie "Die Hard With a Vengeance" ([[clip running through the problem|https://www.youtube.com/watch?v=6cAbgAaEOVE]]). Basically: You have a 3-gallon and a 5-gallon jug that you can fill from a fountain of water. The requirement/problem is to fill one of the jugs with exactly 4 gallons of water. How do you do it? The interesting math lecturer [[Burkard Polster|http://www.qedcat.com/]] (AKA [[Mathologer|https://www.youtube.com/channel/UC1_uAIS3r8Vu6JjXWvastJg]]) goes through [[a solution of this problem|https://www.youtube.com/watch?v=0Oef3MHYEC0]] in an original reformulation of the problem. (he had also written [[a good paper|http://www.qedcat.com/billiards1.pdf]] on it). Polster beautifully reformulates the water jugs problem as a billiards balls bouncing in a parallelogram-shaped table, and comes up with a very elegant solution. [>img[Billiards Jugs|resources/billiards jugs 1.png][resources/billiards jugs.png]] (click on the [[image to zoom in|resources/billiards jugs.png]]) The reformulated solution is so beautiful and elegant (did I already say that? :), that it inspired me to program it as a mobile app using [[Coronalab's|https://coronalabs.com/]] [[physics engine|https://docs.coronalabs.com/api/library/physics/index.html]] (which makes the ball bouncing easy to program :) and the [[Lua programming language|https://www.lua.org/]]. As the ball bounces around the table, it touches the edges at locations indicating the amounts of water being transferred from one water jug to the other. The water quantities (or, reformulated (!), the billiards table "collision coordinates") are shown in the simulation/program console on the right side of the image, and reproduced below: 5 0 2 3 2 0 0 2 5 2 4 3 4 0 1 3 1 0 0 1 5 1 3 3 3 0 0 3 The way to read the results is by row: - you start with 5 gallons in the 5-gallon jug, and 0 in the 3-gallon jug - then you pour from the 5 to the 3 jug, and end up with 2 gallons in one and 3 gallons in the other - next, you empty the 3 jug and are left with 2 in the 5 jug, and 0 in the 3 jug - then you fill up the 5-gallon jug - and you pour 1 gallon into the 3 gallon jug which already has 2 gallons in it, leaving only/exactly 4 gallons in the 5-gallon jug. QED. BTW, the mobile app simulation can run in reverse, starting with filling up the 3-gallon jug first, and produces the following solution sequence: 0 3 3 0 3 3 5 1 0 1 1 0 1 3 4 0 4 3 5 2 0 2 2 0 2 3 5 0 Which again should be interpreted as: - you start with 3 gallons in the 3-gallon jug, and 0 in the 5-gallon jug - then you pour all of it to the 5 jug - then you fill the 3 jug again and so on, with the desired result of 4 gallons in the 5 jug (line 4 0 above) after a few more pourings. Looking at the numbers above: An interesting (and sometimes useful, or as the scene from the movie Die Hard demonstrates, life-saving) result of the simulation is that it can show that in this case we can actually produce any amount of water from 1 gallon to 8 gallons, in increments of 1 gallon, if we need to.
In an interesting article titled [[Doing Mathematics Differently|http://inference-review.com/article/doing-mathematics-differently]], mathematician and computer scientist [[Gregory Chaitin|https://en.wikipedia.org/wiki/Gregory_Chaitin]] writes: >We can compare the complexity of a theory with the complexity of the data very easily because both are finite strings. Leibniz saw that a theory the same size as the data is useless in the sense that it is not possible to cover a debt of ten dollars with another debt of ten dollars. Explanation is a form of compression. If a theory is smaller than the data, then in that case, as in so many others, less is more. A successful explanation is a matter of covering a large debt with a much smaller one. > >If less is more, smaller is better. > >The best theory is the smallest program that generates the data. Chaitin talks about an Algorithmic Information Theory, or AIT. AIT is looking at complex, complexity, compuability, and randomness issues, like: >AIT provides an entirely new perspective on the halting problem. Given a string of bits S, is it possible to prove that S is irreducible? Better, sharper. Given S, is it possible to prove that there exists no program P smaller than S that generates S? > >No such proof is possible. This is an incompleteness result, a measure of the unexpected depth of the concept of complexity, its inner richness. > >A program P is elegant if no program smaller than P produces the same output as P. There may be several elegant programs that produce the same output, and so yield an exciting tie. If we have one of these programs, can we prove that it is an elegant program? > >It is very, very hard. Besides the philosophical questions Chaitin brings up, he also raises questions about program elegance, effectiveness (does it solve the problem) vs. efficiency (does it do it in "the best way" possible); is the solution "beautiful" (elegant)? Here he is looking at brevity of the solution/program, but like any other complex things, this question/aspect is a central one in programming and implementation: sometimes shortness is not the most important aspect. [[Matthew Fuller in his article on Elegance|https://aestech.wikischolars.columbia.edu/file/view/Fuller+-+Elegance+(Software+Studies).pdf]] makes [[this point very clearly|On computer program elegance]]. Chaitin continues: >In 1931, [[Gödel exploded this belief|resources/Boolos-godel-in-single-syllables.pdf]]. The assertion, “I am unprovable,” may be true and unprovable, but it is also bizarre (see also [[The world's shortest explanation of Gödel's theorem]]). This does not look at all like ordinary mathematics. I do not know whether proving that programs are elegant looks like ordinary mathematics. Mathematicians can ignore the proof that I just presented as well. > >What AIT does, however, is to introduce a notion of complexity into the discussion of incompleteness. With Gödel’s original approach you could not tell whether incompleteness was ubiquitous, commonplace, or restricted only to strange, degenerate cases. > >AIT suggests that incompleteness is, in fact, pervasive; it tells us that every mathematical theory has finite complexity, but that the world of pure mathematics has infinite complexity. Just proving that programs are elegant for all possible programs would require infinite complexity. > >AIT makes incompleteness look natural. (easy for Chaitin to say :)
In his flowing, witty, and thoughtful article [[Why Read the Classics?|http://www.nybooks.com/articles/1986/10/09/why-read-the-classics/]], Italo Calvino tries on a few definitions of "Classic": * The classics are the books of which we usually hear people say: “I am rereading…” and never “I am reading….” and he forgivingly adds: >The reiterative prefix before the verb “read” may be a small hypocrisy on the part of people ashamed to admit they have not read a famous book. To reassure them, we need only observe that, however vast any person’s basic reading may be, there still remain an enormous number of fundamental works that he has not read. As for the readers of the classics, Calvino observes: >[...] to read a great book for the first time in one’s maturity is an extraordinary pleasure, different from (though one cannot say greater or lesser than) the pleasure of having read it in one’s youth. Youth brings to reading, as to any other experience, a particular flavor and a particular sense of importance, whereas in maturity one appreciates (or ought to appreciate) many more details and levels and meanings. Classics can both imprint in us (if reading for the first time) or reawaken in us (if re-reading): >Books read then can be (possibly at one and the same time) formative, in the sense that they give a form to future experiences, providing models, terms of comparison, schemes for classification, scales of value, exemplars of beauty—all things that continue to operate even if the book read in one’s youth is almost or totally forgotten. If we reread the book at a mature age we are likely to rediscover these constants, which by this time are part of our inner mechanisms, but whose origins we have long forgotten. A literary work can succeed in making us forget it as such, but it leaves its seed in us. * The classics are books that exert a peculiar influence, both when they refuse to be eradicated from the mind and when they conceal themselves in the folds of memory, camouflaging themselves as the collective or individual unconscious. and more insightful definitions: >Hence, whether we use the verb “read” or the verb “reread” is of little importance. Indeed, we may say: * Every rereading of a classic is as much a voyage of discovery as the first reading. * Every reading of a classic is in fact a rereading. * A classic is a book that has never finished saying what it has to say. About the direct experience of :reading the source": >The reading of a classic ought to give us a surprise or two vis-à-vis the notion that we had of it. For this reason I can never sufficiently highly recommend the direct reading of the text itself, leaving aside the critical biography, commentaries, and interpretations as much as possible. Schools and universities ought to help us to understand that no book that talks about a book says more than the book in question, but instead they do their level best to make us think the opposite. * A classic does not necessarily teach us anything we did not know before. In a classic we sometimes discover something we have always known (or thought we knew), but without knowing that this author said it first, or at least is associated with it in a special way. And this, too, is a surprise that gives a lot of pleasure, such as we always gain from the discovery of an origin, a relationship, an affinity. * The classics are books that we find all the more new, fresh, and unexpected upon reading, the more we thought we knew them from hearing them talked about. And again, the impact of schools: >Naturally, this only happens when a classic really works as such—that is, when it establishes a personal rapport with the reader. If the spark doesn’t come, that’s a pity; but we do not read the classics out of duty or respect, but only out of love. Except at school. And school should enable you to know, either well or badly, a certain number of classics among which—or in reference to which—you can then choose your classics. School is obliged to give you the instruments needed to make a choice, but the choices that count are those that occur outside and after school. * We use the word “classic” of a book that takes the form of an equivalent to the universe, on a level with the ancient talismans. With this definition we are approaching the idea of the “total book,” as Mallarmé conceived of it. * Your classic author is the one you cannot feel indifferent to, who helps you to define yourself in relation to him, even in dispute with him. * A classic is a book that comes before other classics; but anyone who has read the others first, and then reads this one, instantly recognizes its place in the family tree. Calvino argues that one cannot "just read the classics" and ignore the current, daily affairs: >The latest news may well be banal or mortifying, but it nonetheless remains a point at which to stand and look both backward and forward. To be able to read the classics you have to know “from where” you are reading them; otherwise both the book and the reader will be lost in a timeless cloud. This, then, is the reason why the greatest “yield” from reading the classics will be obtained by someone who knows how to alternate them with the proper dose of current affairs. And this does not necessarily imply a state of imperturbable inner calm. It can also be the fruit of nervous impatience, of a huffing-and-puffing discontent of mind. So, * A classic is something that tends to relegate the concerns of the moment to the status of background noise, but at the same time this background noise is something we cannot do without. and * A classic is something that persists as a background noise even when the most incompatible momentary concerns are in control of the situation. And he concludes: >[One should not] believe that the classics ought to be read because they “serve any purpose” whatever. The only reason one can possibly adduce is that to read the classics is better than not to read the classics. > >And if anyone objects that it is not worth taking so much trouble, then I will quote Cioran (who is not yet a classic, but will become one): > > While they were preparing the hemlock, Socrates was learning a tune on the flute. “What good will it do you,” they asked, “to know this tune before you die?”
In his book [[Three Scientists and Their Gods|Three Scientists and Their Gods - Robert Wright]] Robert Wright writes about Edward Fredkin and his reversible computer/logic idea: >[The physicist] [[Rolf Landauer|https://en.wikipedia.org/wiki/Rolf_Landauer]] concluded that computers are indeed necessarily irreversible and thus necessarily dissipate energy, giving off heat. His logic-so seemingly solid that it was not challenged for a decade-went as follows. At the core of every computer on the market are lots of gates-notably “and” gates and “or” gates that translate digital input into digital output. An "and” gate, for example, has two input lines and one output line, all of which can represent—through their level of voltage, typically-either 1 or 0. If the voltage in both input lines represents 1, the output line will then register a 1. But if a representation of 0 enters either input line, or both, the output line will register a 0. So, when the output line reads 0, there is no way of knowing exactly which representations the two input lines previously housed; information loss, and therefore energy dissipation, is inseparable from computation as we know it. The electrons representing information are routinely banished without a trace. And, while the heat they then constitute does “remember” the erased information, the computer itself has no recollection. But Fredkin didn't like the idea of losing information as part of calculating; it didn't seem elegant. >Strictly speaking, Landauer's contention—that, although the universe never forgets, computers always do—didn't contradict Fredkin's belief that the universe is a computer. It is conceivable that an irreversible process at the very core of reality could give rise to the reversible behavior of molecules, atoms, electrons, and the rest. After all, irreversible computers (that is, all computers on the market) can simulate reversible billiard balls. But they do so in a convoluted way, says Fredkin, and the connection between an irreversible substratum and a reversible stratum would, similarly, be tortuous-or, as he puts it, "aesthetically obnoxious." Fredkin prefers to think that the computer underlying reversible reality does its work gracefully. So at Caltech he set out to prove that computers don't have to destroy information-that a reversible computer is in principle possible. So, Fredkin worked on devising a reversible logic gate which would be the basic building block of a reversible computer. >He succeeded. He invented what has since become known as the "Fredkin gate.” Instead of two input lines and one output line, it has three of each, and its input can always be inferred from its output. Fredkin showed that an entire computer could be built with such gates, and that, by using a special logic designed to conserve information, it could do anything any other computer can do. He had on paper, at least-a reversible universal computer. Fredkin's coworker at MIT, Tomasso Toffoli, came up with a variation of the Fredkin Gate, aptly called the Toffoli Gate, which can be used to build all sorts of reversible logic designs and also a reversible computer. I decided to use an example of a 1 bit full adder from a good tutorial titled [["From Truth Tables to Programming Languages: Progress in the Design of Reversible Circuits"|http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.378.6158&rep=rep1&type=pdf]] by Rolf Drechsler and Robert Wille, to demonstrate the some "reversibility concepts", using Python code (to represent the logic operations/gates). <html> <table> <tr> <td> <img src="resources/reversible gates small.png"><br>Toffoli (left) & Fredkin (right) </td> <td> <img src="resources/reversible adder small.png">reversible adder (Toffoli) </td> <td> <img src="resources/adder truth table small.png">reversible adder truth table </td> </tr> </table> </html> and the [[Python implementation|https://trinket.io/python/e9e3a3b888]]: <html> <table> <tr> <td> <img src="resources/Python reversible gates small.png"><p><a href="https://trinket.io/python/e9e3a3b888">Python reversible adder</a> </td> <td> <img src="resources/Python adder truth tables small.png"><p>Python reversible adder truth table </td> </tr> </table> </html>
In a succinctly expressed observation, Michael Shermer, a skeptic's skeptic, simply explained why he thinks we are making progress, as we expand our scientific knowledge. The piece is titled [["At the Boundary of Knowledge"|https://michaelshermer.com/2016/09/at-the-boundary-of-knowledge/]]: >[...] isn’t the history of science also strewn with the remains of failed theories such as phlogiston, miasma, spontaneous generation and the luminiferous aether? Yes, and that is how we know we are making progress. The postmodern belief that discarded ideas mean that there is no objective reality and that all theories are equal is more wrong than all the wrong theories combined. The reason has to do with the relation of the known to the unknown. > >As the sphere of the known expands into the aether of the unknown, the proportion of ignorance seems to grow—the more you know, the more you know how much you don’t know. But note what happens when the radius of a sphere increases: the increase in the surface area is squared while the increase in the volume is cubed. Therefore, as the radius of the sphere of scientific knowledge doubles, the surface area of the unknown increases fourfold, but the volume of the known increases eightfold. It is at this boundary where we can stake a claim of true progress in the history of science. So, while [[Ralph Sockman|https://en.wikipedia.org/wiki/Ralph_Washington_Sockman]] was right when he said: >The larger the island of knowledge, the longer the shoreline of wonder. The above analysis is right too (and delightfully so :), which proves the point [[Niels Bohr|https://en.wikipedia.org/wiki/Niels_Bohr]] was making when he observed: >The opposite of a fact is falsehood, but the opposite of one profound truth may very well be another profound truth.
([[from "The Unreasonable Effectiveness of Mathematics" by Richard W. Hamming|http://www.dartmouth.edu/~matc/MathDrama/reading/Hamming.html]], which [[I write about here|On why Math works for us]]) >Man, so far as we know, has always wondered about himself, the world around him, and what life is all about. We have many myths from the past that tell how and why God, or the gods, made man and the universe. These I shall call theological explanations. They have one principal characteristic in common-there is little point in asking why things are the way they are, since we are given mainly a description of the creation as the gods chose to do it. >Philosophy started when man began to wonder about the world outside of this theological framework. An early example is the description by the philosophers that the world is made of earth, fire, water, and air. No doubt they were told at the time that the gods made things that way and to stop worrying about it. >From these early attempts to explain things slowly came philosophy as well as our present science. Not that science explains "why" things are as they are-gravitation does not explain why things fall-but science gives so many details of "how" that we have the feeling we understand "why." Let us be clear about this point; it is by the sea of interrelated details that science seems to say "why" the universe is as it is. The last point, about science not answering the //why// but rather giving us a scientifically-convincing (rigorous, rational, etc.) //how//-structure, is a point many people miss. It's like a mental/cognitive "bootstrap" structure and process. We "weave" a fabric of concepts, relationships, formulas, connections, etc., and call it an explanation. You can ask "why" and get an explanation, then keep asking why, and keep "drilling down" with more and more why's ([[It's like Alan Kay said about objects and turtles|Smalltalk programs are just objects. It's all objects all the way down. Until you reach turtles.]]). And, at a certain level, it //is// an explanation, but it's a fabric of how-explanations (or deeper and deeper chains of explanations), not a why-explanation. In his article [["Reasonably effective: Deconstructing a miracle"|resources/Wilczek_reasonably1.pdf]] Frank Wilczek makes a similar observation: >Since any answer to a why question can be challenged with a further why, any reasoned argument must terminate in premises for which no further reason can be offered. At that point we pass, necessarily, from reason to faith. [[(a local copy of Hamming's article|resources/Hamming.html]])
In [[an interview on the Farnam Street site|https://www.fs.blog/2016/10/peter-bevelin-seeking-wisdom-mental-models/]], the Swedish investor Peter Bevelin (the author of the excellent book [[Seeking Wisdom - from Darwin to Munger|http://www.valueinvestingworld.com/2007/10/interview-with-peter-bevelin-author-of.html]]) captures some of his "lessons learned" and "pearls of wisdom", inspired by two "sages", mavens, and value investors, [[Charlie Munger|https://www.valuewalk.com/charlie-munger-page/]] and [[Warren Buffett|https://www.valuewalk.com/warren-buffett/]] (of Berkshire Hathaway):
* there are a few basic, time-filtered fundamental concepts, methods, and "tricks" that are good enough. As [Charlie] Munger says, "The more basic knowledge you have the less new knowledge you have to get."
* when I look at something “new”, I try to connect it to something I already understand and if possible get a wider application of an already existing basic concept that I already have in my head.
* as the British statistician George Box said: we shouldn’t be preoccupied with optimal or best procedures but good enough over a range of possibilities likely to happen in practice.
* it's important to "pick ones battles" and focus on the long-term consequences of your actions. As Munger said, “A majority of life's errors are caused by forgetting what one is really trying to do.”
* don't be too quick to jump to conclusions and be judgemental
* you have to "pick your poison" since there is always a set of problems attached with any system or approach – it can’t be perfect. The key is try to move to a better set of problems you can accept
* How efficient and simplified life is when you deal with people you can trust. This is true professionally (your team mates, your manager, your chain of command up to the CEO), and personally (your spouse, your friends, your neighbors)
* luck plays a big role in life.
* most predictions are wrong and that prevention, robustness and adaptability is way more important.
* people or businesses that are foolish in one setting often are foolish in another one ("The way you do anything, is the way you do everything").
* A checklist is no substitute for thinking.
* don't get too involved in details to the point where you can’t see the forest for the trees and you go up too many blind alleys.
* as Warren Buffett said: You only have to be right on a very, very few things in your lifetime as long as you never make any big mistakes.
I believe that Carl Sagan's position on skepticism strikes the right balance between being open to awesomeness and being careful [[not to fall for bull|http://www.skeptical-science.com/bullshit/detecting-bullshit-quick-refresher-carl-sagan/]] (see also his [["Baloney Detection Kit"|https://www.brainpickings.org/2014/01/03/baloney-detection-kit-carl-sagan/]]). (He summed it up once by saying: >Keep an open mind, but not so open that your brains fall out. ) I think that this position also beautifully applies to the corrosive nature/impact of cynicism. >If you’re only skeptical, then no new ideas make it through to you. You never learn anything. You become a crotchety misanthrope convinced that nonsense is ruling the world. (There is, of course, much data to support you.) Since major discoveries at the borderlines of science are rare, experiences will tend to confirm your grumpiness. But every now and then a new idea turns out to be on the mark, valid and wonderful. If you’re too resolutely and uncompromisingly skeptical, you’re going to miss (or resent) the transforming discoveries in science, and either way, you will be obstructing understanding and progress. Mere skepticism is not enough.
From a short article in the New York Times titled [["How to Help Teenagers Embrace Stress"|https://www.nytimes.com/2018/09/19/well/family/how-to-help-teenagers-embrace-stress.html]]: Like in sports and the business world, "no pain, no gain": >To reframe how we think about a phenomenon that has been roundly, and wrongly, pathologized, we should appreciate that healthy stress is inevitable when we operate at the edge of our abilities. Stretching beyond familiar limits doesn’t always feel good, but growing and learning — the keys to school and much of life — can’t happen any other way. Stress is unavoidable, and if (reasonable amounts are) embraced, is a way to develop and improve skills and abilities. Emotional management is important because life is hard. As Buddhism indicates, life is full of "unease" (sometimes translated as "suffering"), so we are advised to develop an attitude and ways to handle it: >According to Jeremy P. Jamieson, an associate professor of psychology at the University of Rochester who studies how stress impacts emotions and performance, “Avoiding stress doesn’t work and is often not possible. To achieve and grow, we have to get outside our comfort zones and approach challenges.” Also, somewhat similar to my observation about the effects of "bootcamps": >Stress is also known to have an inoculating effect. Research shows that people who overcome difficult life circumstances go on to enjoy higher-than-average levels of resilience. In short, achieving mastery in trying situations builds emotional strength and psychological durability.
I came across an article ([[MATHEMATICS EDUCATION:THEORY, PRACTICE & MEMORIES OVER 50 YEARS|resources/Mason-mathematical-action-structures-of-noticing.pdf]]) by [[John Mason|http://www.mathematics.open.ac.uk/People/john.mason]], shining some light on his experience when "doing math", which is (no surprise) quite spiritual in nature: >''STRUCTURED AWARENESS'' >I have often thought and sometimes said, that when I am engaged in my enquiries, I enjoy it most when I am at the overlap between mathematics, psychology and sociology, philosophy and religion. There is something about working on a mathematical problem which is for me profoundly spiritual; something about working on teaching and learning that integrates all three traditional aspects of my psyche (awareness, behaviour and emotion, or more formally, cognition, enaction and affect) as well as will and intention, which themselves derive from ancient psycho-religious philosophies such as expressed in the Upanishads (Radhakrishnan, 1953) and the Bhagavad Gita (Mascaró, 1962; see also Raymond, 1972). I associate this sense of integration with an enhanced awareness, a sense of harmony and unity, a taste of freedom, which is in stark contrast to the habit and mechanicality of much of my existence. Even a little taste of freedom arising in a moment of participating in a choice, of responding freshly rather than reacting habitually is worth striving for. >One way to summarise such experiences is that, in the end, what I learn most about, is myself. This observation is not as solipsistic, isolating and idiosyncratic as it might seem, for in order to learn about myself I need to engage with others (who may, as is the case for hermits, be virtual), and I need to be supported and sustained in those enquiries. A suitable community can be invaluable, though an unsuitable community can be a millstone! I reached this conclusion through realising that when a researcher is reporting their data, and then analysing it, the distinctions they make, the relationships they notice, the properties they abstract all tell me as much about their own sensitivities to notice and dispositions to act as they do about the situation-data being analysed. Indeed I proposed an analogy to the Heisenberg principle in physics: the ratio of the precision of detail of analysis to the precision of detail about the researcher is roughly constant (Mason, 2002, p. 181).
The ACM Alan Turing Award winner [[Judea Pearl|https://en.wikipedia.org/wiki/Judea_Pearl]] quotes Bertrand Russell, and makes some interesting observations, in an [[excellent lecture titled "The Art and Science of Cause and Effect" |http://bayes.cs.ucla.edu/BOOK-2K/causality2-epilogue.pdf]]^^1^^: >If causal information has an empirical meaning beyond regularity of succession, then that information should show up in the laws of physics. But it does not! The philosopher Bertrand Russell made this argument in 1913: “All philosophers,” says Russell, “imagine that causation is one of the fundamental axioms of science^^2^^, yet oddly enough, in advanced sciences, the word ‘cause’ never occurs .... The law of causality, I believe, is a relic of bygone age, surviving, like the monarchy, only because it is erroneously supposed to do no harm.” Another philosopher, Patrick Suppes, who argued for the importance of causality, noted that: “There is scarcely an issue of ‘Physical Review’ that does not contain at least one article using either ‘cause’ or ‘causality’ in its title.” What we conclude from this exchange is that physicists talk, write, and think one way and formulate physics in another. >[...] Fortunately, very few physicists paid attention to Russell’s enigma. They continued to write equations in the office and talk cause – effect in the cafeteria; with astonishing success they smashed the atom, invented the transistor and the laser. Pearl argues that causality is viewed by us in a special way: " ''the laws of physics are all symmetrical, going both ways, while causal relations are unidirectional, going from cause to effect.'' " And to illustrate this symmetry, he gives a simple example, which reminds me of the [["deep understanding of reality"|On multifaceted understanding]] which I think my father was talking about: >Take, for instance, Newton’s law: ''f = m * a''. >The rules of algebra permit us to write this law in a wild variety of syntactic forms, all meaning the same thing – that if we know any two of the three quantities, the third is determined. Yet, in ordinary discourse we say that force causes acceleration – not that acceleration causes force, and we feel very strongly about this distinction^^3^^. >Likewise, we say that the ratio f/a helps us determine the mass, not that it causes the mass. Such distinctions are not supported by the equations of physics, and this leads us to ask whether the whole causal vocabulary is purely metaphysical, “surviving, like the monarchy . . .”. In the 1920's and 30's, Karl Pearson (a strong-willed man, considered to be one of the founders of modern statistics) was fascinated by the concept and implications of correlation, but he vehemently resisted causation: >Beyond such discarded fundamentals as ‘matter’ and ‘force’ lies still another fetish amidst the inscrutable arcana of modern science, namely, the category of cause and effect. As Pearl writes: >It took another 25 years and another strong-willed person, Sir Ronald Fisher, for statisticians to formulate the randomized experiment – the only scientifically proven method of testing causal relations from data, and to this day, the one and only causal concept permitted in mainstream statistics. > >And that is roughly where things stand today. But the world of statistics is still very cautious about causation, as a prominent statistician had remarked: >Considerations of causality should be treated as they have always been treated in statis- tics: preferably not at all but, if necessary, then with very great care. Pearl is wondering how the field of statistics with all the brilliant thinking and thinkers, and powerful tools did not, historically, delve into causation, and he thinks that it had/has to do with the lack of appropriate language (a-la [[Sapir-Whorf|http://en.wikipedia.org/wiki/Sapir-Whorf_Hypothesis]]?) : >Naturally, if we lack a language to express a certain concept explicitly, we can’t expect to develop scientific activity around that concept. > >Scientific development requires that knowledge be transferred reliably from one study to another and, as Galileo showed 350 years ago, such transference requires the precision and computational benefits of a formal language. As an "aside", Pearl, who is not only a statistician but also a computer scientist, mentions some implications and difficulties in CS, as a result of the above: >How should a robot acquire causal information through interaction with its environment? How should a robot process causal information received from its creator– programmer? Pearl focuses on the asymmetry of our views/context as the explanation for why causality is meaningful (let alone very desirable and useful): >If you wish to include the entire universe in the model, causality disappears because interventions disappear – the manipulator and the manipulated lose their distinction. However, scientists rarely consider the entirety of the universe as an object of investigation. In most cases the scientist carves a piece from the universe and proclaims that piece in – namely, the focus of investigation. The rest of the universe is then considered out or background and is summarized by what we call boundary conditions . This choice of ins and outs creates asymmetry in the way we look at things, and it is this asymmetry that permits us to talk about “outside intervention” and hence about causality and cause–effect directionality. And he summarizes: >A causal model contains three ingredients (in addition to using a set of symmetric equations to describe normal conditions): >(i) a distinction between the in and the out ; >(ii) an assumption that each equation corresponds to an independent mechanism and hence must be preserved as a separate mathematical sentence; and >(iii) interventions that are interpreted as surgeries over those mechanisms. At this point Pearl introduces the need and rationale for a new language for dealing with causation: <html> <table> <tr> <td> <b>Expressing observations vs. interventions</b><p><p><p> <img src="resources/algebra of doing 1.png"> </td> <td> <b>Analogously, deriving rules</b><p> <img src="resources/algebra of doing 2.png"> </td> </tr> </table> </html> And this reminds me of Andrea diSessa, [[in his book "Changing Minds")|resources/diSessa - Changing Minds - Chapter1.pdf]] giving an example of the __power of literacy__ to change the way we think and deal with reality (and also [[Examples of the power of math notation]]). <html> <table> <tr> <td> <b>In Pearl's words:</b><p><p> I think you can still get the flavor of this new calculus. It consists of three rules that permit us to transform expressions involving actions and observations into other expres- sions of this type. The first allows us to ignore an irrelevant observation, the third to ignore an irrelevant action; the sec- ond allows us to exchange an ac- tion with an observation of the same fact. What are those symbols on the r ight? They are the “green lights” that the diagram gives us whenever the transformation is legal. </td> <td> <b>And the rules:</b><p> <img src="resources/algebra of doing 3.png"> </td> </tr> </table> </html> At this point, Pearl brings up [[Simpson's paradox]] and highlights the difficulties it presents in determining causation. But, he summarizes the lecture on an optimistic and practical note: >It is true that testing for cause and effect is difficult. Discovering causes of effects is even more difficult. But causality is not mystical or metaphysical. It can be understood in terms of simple processes, and it can be expressed in a friendly mathematical language, ready for computer analysis. and he adds: >This does not solve all the problems of causality, but the power of symbols and mathematics should not be underestimated. >Many scientific discoveries have been delayed over the centuries for the lack of a mathematical language that can amplify ideas and let scientists communicate results. I am convinced that many discoveries have been delayed in our century for lack of a mathematical language that can handle causation. (again, [[echoing diSessa|The power of a new literacy]]). ---- ^^1^^ - see a [[technical explanation (with Python code)|https://medium.com/@akelleh/a-technical-primer-on-causality-181db2575e41]] of key causality concepts titled "A Technical Primer On Causality" by adam kelleher ^^2^^ - See what [[Alison Gopnik had to say about causality|Causality - Alison Gopnik]]. ^^3^^ - which may or may not be [[useful for, or "illuminating" of certain aspects of reality|On multifaceted understanding]].
In a well-thought-out [[blog post titled Nick Bostrom is wrong about the dangers of artificial intelligence|https://ventrellathing.wordpress.com/2015/09/02/nick-bostrom-is-wrong-about-the-dangers-of-artificial-intelligence/]], [[Jeffrey Ventrella|https://ventrellathing.wordpress.com/about/]] brings up several good points, but he has one where he tackles Bostrom using the latter's own "fulcrum" of anthropomorphizing. Ventrella who has been programming AI programs for 20+ years makes a critical point: >''Intelligence is ~Multi-Multi-Multi-Dimensional'' > >Bostrom plots a one-dimensional line which includes a mouse, a chimp, a stupid human, and a smart human. And he considers how AI is traveling along this line, and how it will fly past humans. > [img[Bostrom's linear intelligence lines|./resources/bostrom_intelligence_linear_1.png][./resources/bostrom_intelligence_linear.png]] >Intelligence is not one dimensional. It’s already a bit of a simplification to plot mice and chimps on the same line – as if there were some single number that you could extract from each and compute which is greater. > >>Charles Darwin once said: “It is not the strongest of the species that survives, nor the most intelligent that survives. It is the one that is most adaptable to change.” >''WE HAVE ONLY OURSELVES TO FEAR BECAUSE WE ARE INSEPARABLE FROM OUR AI'' > >We and our AI grow together, side by side. AI evolves with us, for us, in us. It will change us as much as we change it. This is the posthuman condition. You probably have a smart phone (you might even be reading this article on it). Can you imagine what life was like before the internet? For half of my life, there was no internet, and yet I can’t imagine not having the internet as a part of my brain. And I mean that literally. If you think this is far-reaching, just wait another 5 years. Our reliance on the internet, self-driving cars, automated this, automated that, will increase beyond our imaginations. > >We will not be able to separate it from ourselves – increasingly over time. We won’t see it as “other” – we might just see ourselves as having more abilities than we did before. > >[Like explosives and chemical weapons] Those abilities could include a better capacity to kill each other, but also a better capacity to compose music, build sustainable cities, educate kids, and nurture the environment. > >If my interpretation is correct, then Bolstrom’s alarm bells might be better aimed at ourselves. And in that case, what’s new? We have always had the capacity to create love and beauty … and death and destruction.
The brilliant mathematician/engineer/scientist [[Claude Shannon|https://en.wikipedia.org/wiki/Claude_Shannon]] wrote an interesting paper titled [["Prediction and Entropy of Printed English"|https://www.princeton.edu/~wbialek/rome/refs/shannon_51.pdf]], in which he invented a "game" to experientially measure the entropy [the uncertainty regarding which particular letters/words are chosen from a set of all the letters/words] of the English language. From Shannon's article, his description of the Entropy Game: >the subject knows the text up to the current point and is asked to guess the next letter. If he is wrong, he is told so and asked to guess again. This is continued until he finds the correct letter. A typical result with this experiment is shown below. The user needs to guess the next letter in the sentence, and when successful, the number of guesses is shown below that letter, and the user moves to guessing the next letter, all the way to the end of the sentence. (click on the image below to play the game implemented in Python) [img[Shannon's Entropy Game output|resources/entropy game.png][https://trinket.io/python/0459abb846?outputOnly=true&runOption=run]] See a [[Python implementation of Shannon's Entropy Game|https://trinket.io/python/0459abb846?outputOnly=true&runOption=run]]. Brian Christian, in his book [["The Most Human Human"|The Most Human Human - by Brian Christian]] refers to Shannon's game and the concept of entropy in language and its relevance/importance/implications regarding intelligence (human or artificial): >the average entropy of a letter as determined by native speakers playing the Shannon Game comes out to somewhere between 0.6 and 1.3 bits. That is to say, on average, a reader can guess the next letter correctly //half// the time. (Or, from the writer's perspective, as Shannon put it: "When we write English half of what we write is determined by the structure of the language and half is chosen freely.") That is to say, a letter contains, on average, the same amount of information -- 1 bit -- as a coin flip. Christian makes a connection between success in the Entropy Game and success in passing the Turing Test: >Scientists all the way back to Claude Shannon have regarded creating an optimal playing strategy for this game as equivalent to creating an optimal compression method for English. These two challenges are so related that they amount to one and the same thing. In other words, if one can create software that successfully (i.e., with low entropy, ideally 1 guess per letter) guesses letters in the Shannon Game, then this software is the ideal decoder (on the receiving side of a communication channel), achieving the best compression possible on the channel, since it succefully predicts every next letter). >But only now are researchers arguing one step further—that creating an optimal compressor for English is equivalent to another major challenge in the Al world: passing the Turing test. >If a computer could play this game optimally, they say, if a computer could compress English optimally, it'd know enough about the language that it would know the language. We'd have to consider it intelligent—in the human sense of the word. >So a computer, to be humanly intelligent, doesn't even need—as in the traditional Turing test—to respond to your sentences: it needs only complete them. On the "darker side" (or at least potentially somewhat oppressive side) of language prediction: >I'm guessing that if you've ever used a phone to write words—and that is ever closer to being all of us now—you've run up against information entropy. Note how the phone keeps trying to predict what you're saying, what you'll say next. Sound familiar? It's the Shannon Game. > >So we have an empirical measure, if we wanted one, of entropy (and maybe, by extension, "literary" value): how often you disappoint your phone. How long it takes you to write. The longer, arguably, and the more frustrating, the more interesting the message might be. >As much as I rely on predictive text capabilities—sending an average of fifty iPhone texts a month, and now even taking down writing ideas on it—I also see them as dangerous: information entropy turned hegemonic. Why hegemonic? Because every time you type a word that isn't the predicted word, you have to (at least on the iPhone) explicitly reject their suggestion or else it's (automatically) substituted. Most of the time this happens I'm grateful: it smooths out typos made by mis-hitting the key allows for incredibly rapid, reckless texting. But there's the underbelly -- and this was just as true too on my previous standard numerical keypad phone with the T9 prediction algorithm. > >You're gently and sometimes less-than-gently pushed, nudged, bumped into using the language the way the original test group did (This is particularly true when the algorithm doesn't adapt to behavior, and many of them, especially the older ones, don't). As a result, you start unconsciously changing your lexicon to match the words closest to hand. Like the surreal word market in Norton Juster's Phantom Tollbooth, certain words become too dear, too pricey, too scarce. That's crazy. That's no way to treat a language. When I type on my laptop keyboard into my word processor, no such text prediction takes place, so my typos don't fix themselves, and I have to type the whole word to say what I intend, not just the start. But I can write what I want. Perhaps I have to type more keystrokes on the average than if I were using text prediction, but there's no disincentive standing between me and the language's more uncommon possibilities. It's worth it. > >Carnegie Mellon computer scientist Guy Blelloch suggests the following: >One might think that lossy text compression would be unacceptable because they are imagining missing or switched characters. Consider instead a system that reworded sentences into a more standard form, or replaced words with synonyms so that the file can be better compressed. Technically the compression would be lossy since the text has changed, but the "meaning" and clarity of the message might be fully maintained, or even improved. >But—Frost—"poetry is what gets lost in translation." And—it seems—what gets lost in compression?
In a thoughtful WSJ article titled [["The Humanities' decline makes us morally obtuse"|https://www.wsj.com/articles/the-humanities-decline-makes-us-morally-obtuse-1537566941]], Paula Marantz Cohen (English professor at Drexel University) makes a few good observations in support of "good humanities education". Interwoven are my STEM^^1^^-related comments/quotes, in support of complimenting that with "good STEM^^1^^ education"^^2^^ :). (See also [[On "The Purloined Letter" by Edgar Allan Poe]] on what C. P. Snow in 1959 called [["The Two Cultures"|https://en.wikipedia.org/wiki/The_Two_Cultures]]) She opens by stating: >The great works of literature, history and philosophy that used to be at the center of a college education have been shunted to the sidelines or discarded entirely over the past two decades or more. This is a loss on many fronts... >[...] >Few people seem to be able to reconcile two overlapping truths—that someone can have a valid grievance in one context and be guilty of some version of the same thing in another. I see this as a failure of education. > >This is true and reflected in the humanities, but is also true and perceived/observed in the "hard sciences", as expressed for example by the physicist Niels Bohr, who had observed: >>The opposite of a fact is falsehood, but the opposite of one profound truth may very well be another profound truth. >[...] >The assumption these days is that people are monolithic—either completely good or completely bad. The best way to repudiate that assumption it to study the humanities, which illuminate human life in all its complexity. How can you think about crime or misconduct in such an unimaginative way if you’ve read great literature: adultery after “Anna Karenina,” bad parenting after “Death of a Salesman,” political extremism and even murder after “Julius Caesar”? > >The greatness of these works is that they don’t excuse the conduct in question, but they do help explain it as a function of human frailty and misguided motives, sometimes of the most high-minded sort. They expose the back story that otherwise would be hidden from us so that we can, if not sympathize, at least go some way toward understanding what happened. They humanize what would otherwise look like simple stupidity or evil. >[...] >Education is the immersion in “the best which has been thought and said in the world,” as the 19th-century critic and poet Matthew Arnold put it. That “best” can be difficult, unclear, even contradictory. Part of being “the best” is that a work doesn’t reduce to a formula. It can also be written by people who are far from exemplary. >[...] >The emphasis on STEM^^1^^ fields in higher education reflects the need for expertise in a high-tech world. But this has tended to make the “soft” fields of the humanities seem weak and easy. Science, engineering and finance may be hard, but literature, history and philosophy are complex—impossible to resolve with a yes-or-no, right-or-wrong answer. > >This is precisely what constitutes their importance as a tool for living. Metaphysics takes its name from the idea that it goes beyond “hard” science into the realm of moral and intellectual speculation, where no empirical proof is possible. > >To be accurate and fair to the sciences, they also expose human weaknesses, frailty, and limitations, as the astrophysicist Carl Sagan once said: > >>Humans may crave absolute certainty; they may aspire to it; they may pretend, as partisans of certain religions do, to have attained it. But the history of science — by far the most successful claim to knowledge accessible to humans — teaches that the most we can hope for is successive improvement in our understanding, learning from our mistakes, an asymptotic approach to the Universe, but with the proviso that absolute certainty will always elude us. >[...] >The humanities teach understanding, but they also teach humility: that we may be wrong and our enemies may be right, that the past can be criticized without our necessarily feeling superior to it, that people’s professed motives are not the whole story, and that the division of the world into oppressors and victims is a simplistic fairy tale. > >And in the sciences, this humility is coupled with a sense of awe, coming from the realization about the vastness, complexity, and beauty of life and the universe. [[Albert Einstein]] had expressed it nicely: > >>The most beautiful thing we can experience is the mysterious. It is the source of all true art and science. He to whom the emotion is a stranger, who can no longer pause to wonder and stand wrapped in awe, is as good as dead — his eyes are closed. >[...] >We speak about the decline of the humanities without fully recognizing how it has hurt our society. If we want our nation to heal and thrive, we must put the study of literature, history and philosophy back at the center of our curricula and require that students study complex works—not just difficult ones. ---- ^^1^^ STEM = Science, Technology, Engineering, Math ^^2^^ so one cannot avoid the conclusion that well-rounded (and deep-rooted) education (combining the Humanities and the Sciences) is good for you :)
Wisdom means doing the appropriate thing in a given context/situation. Life should not be lived as "always striving for the average/middle/mean". In my mind, it'd be a terrible experience^^1^^ (see the pictures :) [>img[Averages perception|resources/averages perception 1.png][resources/averages perception.png]] I suspect that people are confusing the (Buddhist) concept of ' choosing the "Middle Way" ' with "moderation". But, moderation/temperance is one way to respond, if/when appropriate (but not always). Sometimes, an extreme response (either in one direction or the other, again, depending on the context/appropriateness) is the right and wise response. This is also echoed in [[Aristotle's ethics, where he says|https://plato.stanford.edu/entries/aristotle-ethics/#DocMea]]: "Finding the mean in any given situation is not a mechanical or thoughtless procedure, but requires a full and detailed acquaintance with the circumstances." As a short Buddhist story illustrates: A disciple observed his Zen Master giving certain advice to one person, and the exact opposite advice to another person, and was very troubled by this. After the two people had left, he asked his Master: How can you give one advice to one person, and a totally opposite advice to another? The Master answered: if I see a person riding a bicycle on the road, and he is getting too close to the ditch on the left I yell to him “go right!” and if he is too close to the ditch on the right I yell to him “go left!” ---- ^^1^^ - Having said all of this, sometimes averaging out "perception" is very useful and efficient. For example in computerized pattern recognition, image processing, and machine learning, certain characteristics (or a "signature") of a situation/image can be efficiently and effectively extracted by calculating and using the appropriate averages, basically creating a simplified model or simulation of the actual thing one wants to study/process/analyze. This inspired a project in one of the programming classes I had developed and have been teaching, in a unit on Image Processing: <html> <table> <tr> <td> <img src="resources/hm11.png"><br>5 x 7 cells </td> <td> <img src="resources/hm21.png"><br>11 x 15 cells </td> <td> <img src="resources/hm31.png"><br>21 x 25 cells </td> <td> <img src="resources/hm41.png"><br>31 x 35 cells </td> <td> <img src="resources/hm51.png"><br>51 x 55 cells </td> <td> <img src="resources/hm61.png"><br>150 x 179 pixels </td> </tr> </table> </html>
In an excellent book titled [["When Einstein Walked with Gödel -- Excursions to the Edge of Thought"|https://www.nytimes.com/2018/05/15/books/review/review-when-einstein-walked-with-godel-jim-holt.html]]^^1^^, Jim Holt asks the question whether the Web makes us [["Smarter, Happier, More Productive"|https://docs.google.com/document/d/1T44FTF6bOTpDZQ2osOUoipB4Lp8VqF3y71hAKNc2wt8/edit?usp=sharing]]. >Steven Pinker observes: ‘Knowledge is increasing exponentially; human brainpower and waking hours are not.’ Without the internet, how can we possibly keep up with humanity’s ballooning intellectual output? > >This raises a prospect that has exhilarated many of the digerati. Perhaps the internet can serve not merely as a supplement to memory, but as a replacement for it. ‘I’ve almost given up making an effort to remember anything,’ says Clive Thompson, a writer for Wired, ‘because I can instantly retrieve the information online.’ David Brooks, a New York Times columnist, writes: ‘I had thought that the magic of the information age was that it allowed us to know more, but then I realised the magic of the information age is that it allows us to know less. It provides us with external cognitive servants – silicon memory systems, collaborative online filters, consumer preference algorithms and networked knowledge. We can burden these servants and liberate ourselves.’ > Holt writes: >why not outsource as much of our memory as possible to Google? Carr responds with a bit of rhetorical bluster. ‘The web’s connections are not our connections,’ he writes. ‘When we outsource our memory to a machine, we also outsource a very important part of our intellect and even our identity.’ Then he quotes William James, who in 1892 in a lecture on memory declared: ‘The connecting is the thinking.’ And James was onto something: the role of memory in thinking, and in creativity. What do we really know about creativity? Very little. We know that creative genius is not the same thing as intelligence. > Holt quotes Pinker who observed that geniuses work hard. They immerse themselves in their work. Could this immersion have something to do with stocking the memory? We know about the mechanisms by which the brain consolidates short-term memories into long-term ones. Yet, we don't know why it is better to knock information into our head rather than to get it off the web. But (And therefore?): >It is the connection between memory and creativity, perhaps, that should make us most wary of the web. “As our use of the Web makes it harder for us to lock information into our biological memory, we're forced to rely more and more on the Net's capacious and easily searchable artificial memory," [Nicholas] Carr observes [in his book "The Shallows: What the Internet Is Doing to Our Brains"]. > >But conscious manipulation of externally stored information is not enough to yield the deepest of Breakthroughs: this is what the example of Poincaré^^2^^ suggests. Human memory, unlike machine memory, is dynamic. Through some process we only crudely understand-Poincaré himself saw it as the collision and locking together of ideas into stable combinations—novel patterns are unconsciously detected, novel analogies discovered. And this is the process that Google, by seducing us into using it as a memory prosthesis, threatens to subvert. > >It's not that the web is making us less intelligent; if anything, the evidence suggests it sharpens more cognitive skills than it dulls. It's not that the web is making us less happy, although there are certainly those who, like Carr, feel enslaved by its rhythms and cheated by the quality of its pleasures. It's that the web may be an enemy of creativity. ---- ^^1^^ - searchable spelling: Gödel, Godel, Goedel. ^^2^^ - This is an example of a "typical epiphany" and reaching creative knowledge in a flash of inspiration/intuition. Henri Poincare [[recounts a personal experience|http://vigeland.caltech.edu/ist4/lectures/Poincare%20Reflections.pdf]] where after thinking about a difficult math problem for a while, he had to take a break, and during that break, in what looks like a sudden flash of intuition, he was able to see the solution to his problem: >Just at this time I left Caen, where I was then living, to go on a geological excursion under the auspices of the school of mines. The changes of travel made me forget my mathemati- cal work. Having reached Coutances, we entered an omnibus to go some place or other. At the moment when I put my foot on the step the idea came to me, without anything in my former thoughts seeming to have paved the way for it, that the transformations I had used to define the Fuchsian functions were identical with those of non-Euclidean geometry. I did not verify the idea; I should not have had time, as, upon taking my seat in the omnibus, I went on with a conversation already commenced, but I felt a perfect certainty. On my return to Caen, for conscience’ sake I verified the result at my leisure.
If you have enjoyed Douglas Hofstadter's great (and I mean, GREAT!) book [[Gödel, Escher, Bach|https://en.wikipedia.org/wiki/G%C3%B6del,_Escher,_Bach]] (AKA, GEB), you are going to //love// his book [[Metamagical Themas|https://en.wikipedia.org/wiki/Metamagical_Themas]] (and if you have not read GEB, you are going to //love// Metamagical Themes :) In this book he has a chapter (#4) about self-modifying structures and reflexivity, where he tells the following story about attending a guest lecture by the Computer Science pioneer [[George Forsythe|https://en.wikipedia.org/wiki/George_Forsythe]], where the guest brought up a key point: >[...] the purpose of computing was to do anything that people could figure out how to mechanize. Thus, he [Forsythe] pointed out, computing would inexorably make inroads on one new domain after another, as we came to recognize that an activity that had seemed to require ever-fresh insights and mental imagery could be replaced by an ingenious and subtly worked-out collection of rules, the execution of which would then be a form of glorified drudgery carried out at the speed of light. IBM's [[Deep Blue|https://en.wikipedia.org/wiki/Deep_Blue_%28chess_computer%29]], anyone? His insight was great! Back then (Forsythe died in 1972) Deep Blue was not even an electronic schematic/blueprint (the [[chess match with Garry Kasparov|https://en.wikipedia.org/wiki/Deep_Blue_versus_Garry_Kasparov]] took place in 1996/1997), but Forsythe gave other examples relevant to his ara, like a compiler program, and LISP-like [[self-modifying programs|https://en.wikipedia.org/wiki/Self-modifying_code]] (computer programs which, as part of their execution, change their own code). Forsythe also made a joke about a saying by another CS pioneer - [[Richard Hamming|https://en.wikipedia.org/wiki/Richard_Hamming]] - who famously said: > The purpose of computing is insight, not numbers. On which Forsythe riffed: >The Purpose of Computing Numbers Is Not Yet in Sight.
Adding his perspective to the question of whether mathematics is invented or discovered (see [[Is Math a human invention or a series of discoveries of truths in the real world?]]), the mathematician [[Edward Nelson|https://en.wikipedia.org/wiki/Edward_Nelson]] writes in [["Syntax and Semantics"|https://web.math.princeton.edu/~nelson/papers/s.pdf]]: >The pursuit of mathematics is part of our culture and it has met with many successes. Associated with mathematics is a belief system, its semantics. But the success of what mathematicians actually do is no evidence at all for the validity of the associated belief system. Let me first discuss mathematics psychologically and then logically. I have been doing mathematics for 57 years. What is my experience? Do I discover or invent? Am I a James Cook, finding what was already there, or a Thomas Edison, bringing something new into being? (Cook did not invent Polynesia; Edison did not discover the light bulb.) > >Each mathematician will have a different answer to this question, for doing mathematics is personal and persons are different. But my answer is unequivocal: for me, the experience is one of invention. I start with an idea, a light bulb. I try various things to realize the idea—perhaps something familiar will work. Or perhaps I try carbon, tin, et cetera, until finally (if I am lucky) I hit on tungsten, and it works.1 To say that it works, in mathematics, means that I persuade other mathematicians by a proof, for doing mathematics is social as well as personal. We are far more tightly constrained in our inventions than a musician or painter. > >What is a proof in mathematics? More than anyone else, David Hilbert deserves the credit for answering this question. For several thousand years, Euclid’s great book [10] was held to be the model for a proof. (Though the work of Archimedes is a better model.) But Euclid’s work had serious logical flaws that were corrected by Hilbert. And Hilbert’s plane geometry is flawless. Mathematics is expressed in terms of formulas, which are strings of symbols of various kinds put together according to certain rules. As to whether a string of symbols is a formula or not, there is no dispute: one simply checks the rules of formation. Certain formulas are chosen as axioms. Here there is great scope for imagination and inspiration from one semantics or another, to choose fruitful axioms. Certain rules of inference are specified, allowing one to deduce a formula as conclusion from one or two formulas as premise or premises. Then a proof is a string of formulas such that each one is either an axiom or follows from one or two preceding formulas by a rule of inference. As to whether or not a string of formulas is a proof there is no dispute: one simply checks the rules of formation. This is the syntax of mathematics. > >Is that all there is to mathematics? Yes, and it is enough. Constructing proofs is a serious, deep, and beautiful vocation, one worthy the devotion of a lifetime. And as Galileo observed, the book of nature is written in mathematics, so doing mathematics can increase our understanding of nature: certainly of physics, and increasingly of the other sciences. But some mathematicians feel that syntax is not enough: they want to add semantics. > >Now in defense of semantics it can be said that it is a useful source of inspiration and that it is essential in pedagogy—students who do well in calculus invariably have an understanding of a meaning attached to their calculations. But the question here is the foundational role, if any, of semantics in mathematics.
Douglas Hofstadter wrote about it in his excellent book [[I am a Strange Loop|http://en.wikipedia.org/wiki/I_Am_a_Strange_Loop]], which is much more than the condensed version of his Pulitzer Prize winning book [[Gödel, Escher, Bach|http://en.wikipedia.org/wiki/G%C3%B6del,_Escher,_Bach]]. In a [[short article by Uriah Kriegel|http://uriahkriegel.com/downloads/TLS.pdf]] he summarizes Hofstadter's main analogy of "strage human loopiness" with the following description of a self-referencing^^1^^, emergent construction: >Hofstadter tells a wonderful story about the emergence of symbolic thought from neural activity. Imagine a pool table with a million small interacting magnetic marbles (“simms”) on it. These simms careen about the space of the pool table, which he calls the “careenium”. In some circumstances, the simms get magnetized to each other, and may form ball-shaped clusters – “simmballs”. The behaviour of single simms is random, but that of simmballs is not. The simmballs move around inside the careenium depending on what kind of external forces impinge on the careenium’s external walls. Thus the behaviour of simmballs inside the careenium comes to reflect conditions outside it. >Our minds, says Hofstadter, work in just this way. Inside the cranium (careenium) are millions of nervous cells whose behaviour is more or less meaningless. But sometimes large clusters of cells coordinate their behaviour in response to the way the external world impinges on parts of the cranium, such as the retina or the ear drums. When they do, these clusters come to constitute symbols (simmballs), symbols that represent external conditions in a sustained manner that effectively constitutes a rudimentary awareness of the external world. The moral is that although we cannot find anything like symbolic thought or awareness when we look at individual brain cells, if we widen our view and consider slightly more abstract and more spread-out structures and patterns within the brain, we just might. >What is true for awareness of things other than oneself is true also for self-awareness. One special symbol which takes more time to form is the “I” symbol. If the careenium developed a simmball with which to represent its own operations, it would come to be a self-referential system and have an “I”. Our cranium does have a symbol that represents itself, and it is therefore self-aware. Importantly, however, our symbolic representations have a somewhat “coarse grain”, as philosophers say. When we represent an ice cube, for example, we are aware of it simply as a single, homogenous, clear-pinkish cube. We are not aware of the millions of hydrogen and oxygen atoms making it up. Likewise, when we represent ourselves, we are not aware of the millions of neurons inside our brain, but rather of the various symbols that clusters of them make up. That is to say, the cranium is aware of itself precisely as a theatre of ideas, desires, and hopes, not as a container of cerebral molecules buzzing about meaninglessly. And that is why we experience our mental life in those terms, even though ultimately it all rests on the purposeless activities of so many individually insentient nervous cells. David Gelernter (of [[Mirror Worlds|http://en.wikipedia.org/wiki/Mirror_Worlds]] fame) wrote in an [[interesting article in Commentary|http://www.commentarymagazine.com/article/the-closing-of-the-scientific-mind/]]: >Computationalists believe that the mind is embodied by the brain, and the brain is simply an organic computer. But in fact, the mind is embodied not by the brain but by the brain and the body, intimately interleaved. Emotions are mental states one feels physically; thus they are states of mind and body simultaneously. (Angry, happy, awestruck, relieved—these are physical as well as mental states.) Sensations are simultaneously mental and physical phenomena. Wordsworth writes about his memories of the River Wye: “I have owed to them/In hours of weariness, sensations sweet,/Felt in the blood, and felt along the heart/And passing even into my purer mind…” >Where does the physical end and the mental begin? The resonance between mental and bodily states is a subtle but important aspect of mind. Bodily sensations bring about mental states that cause those sensations to change and, in turn, the mental states to develop further. You are embarrassed, and blush; feeling yourself blush, your embarrassment increases. Your blush deepens. “A smile of pleasure lit his face. Conscious of that smile, [he] shook his head disapprovingly at his own state.” (Tolstoy.) As Dmitry Merezhkovsky writes brilliantly in his classic Tolstoy study, “Certain feelings impel us to corresponding movements, and, on the other hand, certain habitual movements impel to the corresponding mental states….Tolstoy, with inimitable art, uses this convertible connection between the internal and the external.” >All such mental phenomena depend on something like a brain and something like a body, or an accurate reproduction or simulation of certain aspects of the body. However hard or easy you rate the problem of building such a reproduction, computing has no wisdom to offer regarding the construction of human-like bodies—even supposing that it knows something about human-like minds. (see another treatment from a Models and Analogs perspective in [[On Metaphors and Mental Models - by Patrick O’Shaughnessy]]). ---- ^^1^^ - an example of a self reference a-la Hofstadter [<img[self reference sentence|resources/self reference.jpeg][resources/self reference 1.jpeg]]
From the book //Homer and the Question of Strife// by Jessica Wolfe: In many cases, Erasmus proposes “figurative applications” for his Homeric proverbs that are quite “distant” from their original meanings or contexts – a process he refers to as detorqueri [torquing; perverting]- or cites Homeric verses in “ways that seem quite opposed to Homer's meanings”. The preface to the Homeric adages explains how the special flexibility of Homeric epic encourages an interpretive license that he “would not allow ... with other poets” [(n)eque vero idem permiserim in reliquis poetis], because a process of accommodation allows Homer's "words [to be] stretched [detorseris] to give a vastly different sense,” and new meanings infused into the most familiar Homeric lines. This practice of citing proverbial lines in surprising or incongruous contexts is largely responsible for producing the “novelty” that lends many of the adages their wit. According to Erasmus, an idea "launched like a javelin in proverbial form strikes with sharper point on the hearer's mind and leaves implanted barbs of thought” [sententia proverbio quasi vibrata feriat acrius auditoris animum, et aculeos quosdam cogitationum relinquat infixos] such that disputes which cannot be solved by arguments are “evaded by a jest” [ioco eludi] in the form of an aptly deployed adage. This is precisely how Erasmus and many of his early sixteenth-century readers make use of his Homeric adages: as a vehicle for resolving, deflecting, or managing contention through wit. """ """ Jorge Luis Borges had a similar sentiment: > I think that the reader should enrich what he is reading. He should misunderstand the text; he should change it into something else.
The coding practice site [[Code Wars|https://www.codewars.com/]] (don't like the name, but like aspects of some of the educational concepts and potential) has a [[Kata|https://www.codewars.com/about]] called [["Josephus Survivor"|https://www.codewars.com/kata/josephus-survivor/python]] (the historic background^^1^^ [[from the Shippensburg University site|http://webspace.ship.edu/deensley/mathdl/joseph.html]]).
After going through it and actually "playing out the scenario of the problem" (dry-running it with pencil and paper; always an excellent idea!), I came up with [[the following Python solution|https://trinket.io/python/3288a0ebfa]]^^2^^:
{{{
# Solution 1:
def josephus_survivor_1(n,k):
people = range(1, n+1)
pop_index = -1
while len(people) > 1:
pop_index = (pop_index + k) % len(people)
gone = people.pop(pop_index)
pop_index -= 1
return people[0]
print josephus_survivor_1(7, 3) # prints 4
}}}
Since solution 1 successfully solves the challenge, the site enables you to look at other solutions other people had submitted, so you can learn from them (as I had said, I like the idea :), an I found the following solution:
{{{
# Solution 2:
def josephus_survivor_2(n, k):
v = 0
for i in range(1, n + 1):
v = (v + k) % i
return v + 1
print josephus_survivor_2(7, 3) # prints 4
}}}
Comparing the two solutions, one can definitely say that solution 2 is shorter and more "concise"; and some people may claim it's more "elegant" than solution 1.
These are important aspects of good programming, and
as the [[Zen of Python|https://www.python.org/dev/peps/pep-0020/]] points out, and keeping the 2 solutions in mind:
>Beautiful is better than ugly.
>Simple is better than complex.
>Flat is better than nested.
>Sparse is better than dense.
>[P]racticality beats purity.
But (as "sage advice" is often not black-or-white), the [[Zen of Python|https://www.python.org/dev/peps/pep-0020/]] __''also''__ points out:
>Explicit is better than implicit.
>Readability counts.
>If the implementation is hard to explain, it's a bad idea.
>If the implementation is easy to explain, it may be a good idea.
So in light of this, looking at ''Solution 1'', one can say:
* it tries to make the code follow the model of solving this problems in actuality
** it uses meaningful names (e.g., people, pop_index, gone)
** the algorithm follows the physical actions you'd make if you "played" the problem:
*** starting (indexing) with a certain person (pop_index),
*** moving around the circle of people (pop_index + k) and circling around (% len(people))
*** repeating this until there is only one survivor (while len(people) > 1)
* this "explicit" modeling allows one to see/check how things are progressing throughout the simulation/run.
** so, for example, one can print the list ("circle of people"), as people are eliminated ("gone"):
{{{
# Solution 1:
def josephus_survivor_2(n,k):
people = range(1, n+1)
index = -1
while len(people) > 1:
print people
index = (index + k) % len(people)
gone = people.pop(index)
print 'eliminating', gone, 'to result in:'
index -= 1
return people[0]
}}}
and get the following progression/visibility/explanatory view:
{{{
We start with:
[1, 2, 3, 4, 5, 6, 7]
eliminating 3 to result in:
[1, 2, 4, 5, 6, 7]
eliminating 6 to result in:
[1, 2, 4, 5, 7]
eliminating 2 to result in:
[1, 4, 5, 7]
eliminating 7 to result in:
[1, 4, 5]
eliminating 5 to result in:
[1, 4]
eliminating 1 to result in:
4
}}}
On the other hand, looking at ''Solution 2'', one can definitely appreciate the brevity and "cleanness" of the solution, but
* it's not easy to see nor explain why it works, since the modeling/implementation doesn't seem to follow the "natural activities" or actions one would follow to carry out the plan
* one cannot print any "meaningful status" or progression, since, for example:
{{{
# Solution 2:
def josephus_survivor_1(n, k):
v = 0
for i in range(1, n + 1):
print v
v = (v + k) % i
print 'which leaves:'
return v + 1
}}}
results in
{{{
0
0
1
1
0
3
0
which leaves:
4
}}}
which is "not revealing much" (and the solution is so "compact" and "concise" that there is not much you can "peek into" to get an idea of the workings... :(
If you think about it, these 2 different solutions exemplify in a sense a "mini-version" of the [["black box" phenomenon|https://www.kdnuggets.com/2017/04/ai-machine-learning-black-boxes-transparency-accountability.html]] in AI (Artificial Intelligence), making it difficult for some AI/ML (Machine Learning) systems/architectures/approaches to "explain" the what/why/how regarding the solution (making it less "understandable", "transparent", and more difficult to "prove correct").
Here we have 2 solutions which produce correct results, but one is more "transparent" and helpful in understanding the solution (and problem?). This solution is "straight forward" since it simulates the actions in the real world (which is not always essential to do, but often helpful), and is simple, clear (enough) and easy to extend and enhance (to add explanatory power and/or transparency, for example).
And, it still stays close to the spirit of the Zen of Python :)
----
^^1^^ [[from the Shippensburg University site|http://webspace.ship.edu/deensley/mathdl/joseph.html]]:
>In the Jewish revolt against Rome, Josephus and 39 of his comrades were holding out against the Romans in a cave. With defeat imminent, they resolved that, like the rebels at Masada, they would rather die than be slaves to the Romans. They decided to arrange themselves in a circle. One man was designated as number one, and they proceeded clockwise killing every seventh man... Josephus (according to the story) was among other things an accomplished mathematician; so he instantly figured out where he ought to sit in order to be the last to go. But when the time came, instead of killing himself he joined the Roman side.
^^2^^ You can play with [[my Scratch simulation|https://scratch.mit.edu/projects/227161968/#fullscreen]]:
[img[Josephus Survivor Scratch|resources/Josephus Scratch small.png][https://scratch.mit.edu/projects/227161968/#fullscreen]]
The [[Nobel Laureate Steven Weinberg|https://www.nobelprize.org/prizes/physics/1979/weinberg/biographical/]] (Physics, 1979), [[mentions|https://www.brainpickings.org/2017/02/01/we-are-all-stardust-steven-weinberg-interview/]] that we all desire simplicity, in science (through unification and abstraction), religion (moving from polytheism to monotheism)^^1^^, and life in general. On the scientific effort of unification (leading to a "Theory of Everything"), Weinberg said: >We want to achieve a simpler understanding of nature. And the path to simplicity is unification. But, he is cautious about the end result, and points out a potential limit/wall in our understanding/unification/simplification: >Another question is whether our brains are powerful enough to even understand these increasingly comprehensive laws. In the end, dogs can’t be trained to solve the Schrödinger equation. which is echoed in [[Perhaps there are thoughts we cannot think]]. ---- ^^1^^ Weinberg said: >The desire for one God and for a theory of the whole cosmos might have the same cause. Monotheism developed because people found polytheism too complicated. And just as it’s less satisfying to pin storms on Zeus, plagues on Apollo, and the crop yield on Demeter, we physicists would rather have a unified explanation of the world than the complex standard model.
I finally got around to reading Thomas Nagel's [[What is it like to be a bat|https://warwick.ac.uk/fac/cross_fac/iatl/study/ugmodules/humananimalstudies/lectures/32/nagel_bat.pdf]]. In his essay he makes the following points, denoted with * and my comments, denoted with ** : * Every reductionist has his favorite analogy from modern science. It is most unlikely that any of these unrelated examples of successful reduction will shed light on the relation of mind to brain. ** This is because the mind-body problem is unique, and unlike the water-H~~2~~0 problem or the Turing machine-IBM machine problem or the lightning-electrical discharge problem or the gene-DNA problem or the oak tree-hydrocarbon problem. * philosophers share the general human weakness for explanations of what is incomprehensible in terms suited for what is familiar and well understood, though entirely different. ** This is similar to points Douglas Hofstadter makes about humans thinking, reasoning, and speaking with analogies __all the time__, and the need to not confuse an analogy with the actual thing itself. * no matter how the [physical] form may vary, the fact that an organism has conscious experience at all means, basically, that there is something it is like to //be// that organism. [...] fundamentally an organism has conscious mental states if and only if there is something that it is like to //be// that organism -- something it is like //for// the organism. We may call this the subjective character of experience. ** again, one has to be careful not to equate the sense of "to be //like// something" (analogy) with "to be something" (identity). * If physicalism is to be defended, the phenomenological features must themselves be given a physical account. But when we examine their subjective character it: seems that such a result is impossible. The reason is that every subjective phenomenon is essentially connected with a single point of view, and it seems inevitable that an objective, physical theory will abandon that point of view. ** Nagel puts the point on the difficulty, since the (by definition) uniqueness of a subjective point of view flies (bats? :) in the face of the objectivity of explanations in terms of language, and so on. * I [Nagel] assume we all believe that bats have experience. ** he selected bats since they are mammals, and poses a range of activity and a sensory apparatus so different from ours that the problem I want to pose is exceptionally vivid. * bat sonar, though clearly a form of perception, is not similar in its operation to any sense that we possess, and there is no reason to suppose that it is subjectively like anything we can experience or imagine. This appears to create difficulties for the notion of what it is like to be a bat. We must consider whether any method will permit us to extrapolate to the inner life of the bat from our own case, and if not, what alternative methods there may be for under- standing the notion. * Our own experience provides the basic material for our imagination, whose range is therefore limited. ** this point is similar to that made about the imagination and creativity, which claims that we create our worldview by merely combining the "raw materials" in new/unique combinations. * [Again, one has to be careful not to fall into the trap of describing/explaining] only what it would be like for me to behave as a bat behaves [since] that is not the question. I want to know what it is like for a //bat// to //be// a bat. Yet if I try to imagine this, I am restricted to the resources of my own mind, and those re- sources are inadequate to the task. I cannot perform it either by imagining additions to my present experience, or by imagining segments gradually subtracted from it, or by imagining some combination of additions, subtractions, and modifications. * To the extent that I could look and behave like a wasp or a bat without changing my fundamental structure, my experiences would not be anything like the experiences of those animals. * Even if I could by gradual degrees be transformed into a bat, nothing in my present constitution enables me to imagine what the experiences of such a future stage of myself thus metamorphosed would be like. ** this logical conclusion is similar to the one made (for example, by Alan Watts) about trying to think/reason/imagine what it would feel like to be dead. Even though emotionally hard to accept this, logic points out that "when you are dead, you are dead" and by definition there is no //you// to feel the "dying feelings". * So if extrapolation from our own case is involved in the idea of what it is like to be a bat, the extrapolation must be incompletable. We cannot form more than a schematic conception of what it is like. ** in other words, we can extrapolate, categorize, draw similarities, and so on, but this boils down to just building mental models of what we think it's like to be a bat. * we believe that these experiences also have in each case a specific subjective character, which it is beyond our ability to conceive. And if there is conscious life elsewhere in the universe, it is likely that some of it will not be describable even in the most general experiential terms available to us. (The problem is not confined to exotic cases, however, for it exists between one person and another. The subjective character of the experience of a person deaf and blind from birth is not accessible to me, for example, nor presumably is mine to him. This does not prevent us each from believing that the other's experience has such a subjective character.) ** the parenthetical observation is definitely "sad but true". * If anyone is inclined to deny that we can believe in the existence of facts like this whose exact nature we cannot possibly conceive, he should reflect that in contemplating the bats we are in much the same position that intelligent bats or Martians would occupy if they tried to form a conception of what it was like to be us. ** Nagel uses "switching positions" as an effective (and fitting the topic :) tool to clarify a point. * The fact that we cannot expect ever to accommodate in our language a detailed description of Martian or bat phenomenology should not lead us to dismiss as meaningless the claim that bats and Martians have experiences fully comparable in richness of detail to our own. * It would be fine if someone were to develop concepts and a theory that enabled us to think about those things; but such an under- standing may be permanently denied to us by the limits of our nature. And to deny the reality or logical significance of what we can never describe or understand is the crudest form of cognitive dissonance. ** this point is similar to [[the point Richard Hamming, Eugene Wigner, Frank Wilczek, and others make|Perhaps there are thoughts we cannot think]] about the possibility, or actually, the inevitability, of the existence of thoughts and things we can not think and/or experience. *** Nagel: My realism about the subjective domain in all its forms implies a belief in the existence of facts beyond the reach of human concepts. Certainly it is possible for a human being to believe that there are facts which humans never will possess the requisite concepts to represent or comprehend. Indeed, it would be foolish to doubt this, given the finiteness of humanity's expectations. After all, there would have been transfinite numbers even if everyone had been wiped out by the Black Death before Cantor discovered them *** Nagel: But one might also believe that there are facts which could not ever be represented or comprehended by human beings, even if the species lasted forever-simply because our structure does not permit us to operate with concepts of the requisite type. ** Nagel: Reflection on what it is like to be a bat seems to lead us, therefore, to the conclusion that there are facts that do not consist in the truth of propositions expressible in a human language. We can be compelled to recognize the existence of such facts without being able to state or comprehend them. * There is a sense in which phenomenological facts are perfectly objective: one person can know or say of another what the quality of the other's experience is. They are subjective, however, in the sense that even this objective ascription of experience is possible only for someone sufficiently similar to the object of ascription to be able to adopt his point of view-to understand the ascription in the first person as well as in the third, so to speak. * The objective nature of the things picked out by these concepts [like rainbows, lightning, clouds] could be apprehended by him [a Martian] because, although the concepts themselves are connected with a particular point of view and a particular visual phenomenology, the things apprehended from that point of view are not: they are observable from the point of view but external to it; hence they can be comprehended from other points of view also, either by the same organisms or by others * In speaking of the move from subjective to objective characterization, I wish to remain noncommittal about the existence of an end point, the completely objective intrinsic nature of the thing, which one might or might not be able to reach. It may be more accurate to think of objectivity as a direction in which the understanding can travel. And in understanding a phenomenon like lightning, it is legitimate to go as far away as one can from a strictly human viewpoint. ** Here, I think that Nagel avoids a trap of trying to define or establish a "True", Objective Reality. Since we are not sure we will ever get there (or get out of our "cage" (head, subjective point of view), there is no point in trying to claim the ability/possibility to Objectively know The Truth. * The less [a phenomenal description] depends on a specifically human viewpoint, the more objective is our description. It is possible to follow this path because although the concepts and ideas we employ in thinking about the external world are initially applied from a point of view that involves our perceptual apparatus, they are used by us to refer to things beyond themselves- toward which we have the phenomenal point of view. Therefore we can abandon it in favor of another, and still be thinking about the same things. * Experience itself, however, does not seem to fit the pattern. The idea of moving from appearance to reality seems to make no sense here. [...] Certainly it appears unlikely that we will get closer to the real nature of human experience by leaving behind the particularity of our human point of view and striving for a description in terms accessible to beings that could not imagine what it was like to be us. * It would be a mistake to conclude that physicalism must be false. Nothing is proved by the inadequacy of physicalist hypotheses that assume a faulty objective analysis of mind. It would be truer to say that physicalism is a position we cannot understand because we do not at present have any conception of how it might be true. ** Nagel: This explains the magical flavor of popular presentations of fundamental scientific discoveries, given out as propositions to which one must subscribe without really understanding them. For example, people are now told at an early age that all matter is really energy. But despite the fact that they know what "is" means, most of them never form a conception of what makes this claim true, because they lack the theoretical background. ** Nagel: At the present time the status of physicalism is similar to that which the hypothesis that matter is energy would have had if uttered by a pre-Socratic philosopher. We do not have the beginnings of a conception of how it might be true. In order to understand the hypothesis that a mental event is a physical event, we require more than an understanding of the word "is." The idea of how a mental and a physical term might refer to the same thing is lacking, and the usual analogies with theoretical identification in other fields fail to supply it. * Very little work has been done on the basic question (from which mention of the brain can be entirely omitted) whether any sense can be made of experiences' having an objective character at all. Does it make sense, in other words, to ask what my experiences are really like, as opposed to how they appear to me? We cannot genuinely understand the hypothesis that their nature is captured in a physical description unless we understand the more fundamental idea that they have an objective nature (or that objective processes can have a subjective nature). And Nagel concludes: * [We should regard it] as a challenge to form new concepts and devise a new method-an objective phenomenology not dependent on empathy or the imagination. Though presumably it would not capture everything, its goal would be to describe, at least in part, the subjective character of experiences in a form comprehensible to beings incapable of having those experiences. ** One might try, for example, to develop concepts that could be used to explain to a person blind from birth what it was like to see. * it seems unlikely that any physical theory of mind can be contemplated until more thought has been given to the general problem of subjective and objective. Otherwise we cannot even pose the mind- body problem without sidestepping it. It seems to me that throughout the essay, and especially in the last part, which Nagel calls " a speculative proposal", he advocates for developing a new framework to think and speak about mental phenomena. Sort of a new ~Domain-Specific Language (but definitely more than just a language; almost like a New Science). This concept of "A New Science" is, I think, captured in [[an article in the New Yorker|https://www.newyorker.com/books/page-turner/thomas-nagel-thoughts-are-real]] by Richard Brody: >Nagel offers mental activity as a special realm of being and life as a special condition—in the same way that biology is a special realm of science, distinct from physics. His argument is that, if the mental things arising from the minds of living things are a distinct realm of existence, then strictly physical theories about the origins of life, such as Darwinian theory, cannot be entirely correct. Life cannot have arisen solely from a primordial chemical reaction, and the process of natural selection cannot account for the creation of the realm of mind. Biology, in his view, becomes a variety of science that is radically distinct from physics—it deals with a vast and crucial realm of phenomena that physics doesn’t and can’t encompass, precisely because they’re aspects of living things that are not physical. Or As Nagel puts it: >subjective consciousness, if it is not reducible to something physical, … would be left completely unexplained by physical evolution—even if the physical evolution of such organisms is in fact a causally necessary and sufficient condition for consciousness. Brody, in his New Yorker article puts it a bit differently, suggesting that Nagel suggests a "New Philosophy" (not just a New Science"), or maybe a Theory of Everything: >Nagel’s thesis has, I think, similarly radical consequences for philosophy itself. His argument implies that consciousness—indeed, mental life, whether conscious or not—is not atomic but holistic: there is no such thing as a piece or an atom of experience, but, rather, a mind at a given moment is flooded with an incalculable number of perceptions, memories, ideas, judgments, and desires. Even enumerating them in the plural is a little silly, because it implies the ability to isolate them as singular events or things. Therefore, philosophy, in order to account for mental life, will need to turn aside from isolated experiments in logic and argumentation in favor of rough-edged, life-sized chunks—historical events and figures, works of art, artists themselves, cities, countries, languages, human dramas of all sorts, lived or imagined.
In a [[very well-written, very readable, and thought-provoking paper|resources/Hamming.html]]^^1^^, Richard Hamming makes a strong case (in response to Wigner^^2^^, which is interesting to compare with [[Wilczek's article "Reasonably effective: Deconstructing a miracle"|resources/Wilczek_reasonably1.pdf]]^^3^^) that: >The Postulates of Mathematics Were Not on the Stone Tablets that Moses Brought Down from Mt. Sinai. >...We begin with a vague concept in our minds, then we create various sets of postulates, and gradually we settle down to one particular set. In the rigorous postulational approach the original concept is now replaced by what the postulates define. Where he is coming from seems similar to how Nick Bostrom and Janna Levin look at [[the anthropic bias|On Anthropic Bias, or Was the Universe Made for Us?]]. He takes the very fundamental (and seemingly simple) concept of numbers, and briefly (and succinctly) shows how they evolved over time and with our needs and circumstances. >Mathematics has been made by man and therefore is apt to be altered rather continuously by him. Perhaps the original sources of mathematics were forced on us, but as in the example I have used we see that in the development of so simple a concept as number we have made choices for the extensions that were only partly controlled by necessity and often, it seems to me, more by aesthetics. We have tried to make mathematics a consistent, beautiful thing, and by so doing we have had an amazing number of successful applications to the real world. Paraphrasing Hamming, he starts with the __integers__, which arose from counting (and as the famous mathematician Kronecker once said, "God made the integers, man did the rest"). Then we (the Greeks?) had to "invent" __fractions__, which are not counting numbers; they are measuring numbers. This extension allowed us to apply the same rules and manipulations to both integers and fraction, but added benefits in measurement and division. Then we extended the __rational number system__ to include the __algebraic numbers__. (It was the simple desire to measure lengths that did it...How can one deny that there is a number to measures the length of the diagonal of a unit square (namely, the square root of 2)). Then, the measurement of the circumference of a circle with respect to its diameter soon forced us to consider the ratio called pi. Thus, by a further suitable extension of the earlier ideas of numbers, the __transcendental numbers__ were admitted consistently into the number system. Further tinkering with the number system brought both the __number zero__ and the __negative numbers__. The next step is the __complex number system__ and the realization by Cardano and others that the same formal operations on the symbols for complex numbers would give meaningful results. (as well as Hamming's feeling that "God made the universe out of complex numbers."). (see also the [[infinitesimals|Infinitesimals are significant (and meaningful?)]] which were added to this evolving/expanding "zoo" of mathematical creations/creatures). And he summarizes: >from simple counting using the God-given integers, we made various extensions of the ideas of numbers to include more things. Sometimes the extensions were made for what amounted to aesthetic reasons, and often we gave up some property of the earlier number system. Thus we came to a number system that is unreasonably effective even in mathematics itself; witness the way we have solved many number theory problems of the original highly discrete counting system by using a complex variable. >From the above we see that one of the main strands of mathematics is the extension, the generalization, the abstraction - they are all more or less the same thing-of well-known concepts to new situations. But note that in the very process the definitions themselves are subtly altered. Therefore, what is not so widely recognized, old proofs of theorems may become false proofs. The old proofs no longer cover the newly defined things. The miracle is that almost always the theorems are still true; it is merely a matter of fixing up the proofs. So here are Hamming's explanations of the unreasonable effectiveness of mathematics: 1. We see what we look for... >we approach the situations with an intellectual apparatus so that we can only find what we do in many cases. It is both that simple, and that awful. What we were taught about the basis of science being experiments in the real world is only partially true. Eddington went further than this; he claimed that a sufficiently wise mind could deduce all of physics. I am only suggesting that a surprising amount can be so deduced. Eddington gave a lovely parable^^4^^ to illustrate this point. He said, "Some men went fishing in the sea with a net, and upon examining what they caught they concluded that there was a minimum size to the fish in the sea." (see [[Simpson's paradox]]). 2. We select the kind of mathematics to use. >Mathematics does not always work. When we found that scalars did not work for forces, we invented a new mathematics, vectors. And going further we have invented tensors...we select the mathematics to fit the situation, and it is simply not true that the same mathematics works every place. 3. Science in fact answers comparatively few problems (see also [[On scientific vs. religious explanation|On scientific vs. religious explanation]]). >science has contributed nothing to the answers [to the questions about what Truth, Beauty, or Justice are], nor does it seem to me that science will do much in the near future. So long as we use a mathematics in which the whole is the sum of the parts we are not likely to have mathematics as a major tool in examining these famous three questions. >[T]o generalize, almost all of our experiences in this world do not fall under the domain of science or mathematics. Furthermore, we know (at least we think we do) that from Gödel's theorem^^5^^ there are definite limits to what pure logical manipulation of symbols can do, there are limits to the domain of mathematics^^6^^. 4. The evolution of man provided the model. >Some people...have further claimed that Darwinian evolution would naturally select for survival those competing forms of life which had the best models of reality in their minds-"best" meaning best for surviving and propagating. [[Perhaps there are thoughts we cannot think]]. ---- The originals articles: ^^1^^ Richard Hamming on [["The Unreasonable Effectiveness of Mathematics"|http://www.dartmouth.edu/~matc/MathDrama/reading/Hamming.html]] ^^2^^ Eugene Wigner on The [["Unreasonable Effectiveness of Mathematics in the Natural Sciences"|http://www.dartmouth.edu/~matc/MathDrama/reading/Wigner.html]] ^^3^^ Frank Wilczek on [["Reasonably effective: I. Deconstructing a miracle"|http://ned.ipac.caltech.edu/level5/March07/Wilczek/Wilczek.html]]. In his article Wilczek casts a critical (not to say doubtful) eye on the power and potential of mathematics when he asks: [[Can mathematics be used to extract qualitative predictions from physical laws - or, for that matter, useful laws from data - automatically?]] (and pointedly answers: Perhaps, but the omens aren't auspicious.) ^^4^^ This parable is [[referenced by Bostrom|http://www.anthropic-principle.com/?q=book/chapter_1#1a]], too: > How big is the smallest fish in the pond? You catch one hundred fishes, all of which are greater than six inches. Does this evidence support the hypothesis that no fish in the pond is much less than six inches long? Not if your net can’t catch smaller fish. > >Knowledge about limitations of your data collection process affects what inferences you can draw from the data. In the case of the fish-size-estimation problem, a selection effect—the net’s sampling only the big fish—vitiates any attempt to extrapolate from the catch to the population remaining in the water. Had your net instead sampled randomly from all the fish, then finding a hundred fishes all greater than a foot would have been good evidence that few if any of the fish remaining are much smaller. ^^5^^ See [[Gödel's Second Incompleteness Theorem Explained in Words of One Syllable|resources/Boolos-godel-in-single-syllables.pdf]], which can be compared with [[The world's shortest explanation of Gödel's theorem]]. ^^6^^ From Douglas R. Hofstadter's book, Gödel, Escher, Bach: >All the limitative theorems of metamathematics and the theory of computation suggest that once the ability to represent your own structure has reached a certain critical point, that is the kiss of death; it guarantees that you can never represent yourself totally. Gödel’s Incompleteness Theorem, Church’s Undecidability Theorem, Turing’s Halting Theorem, Tarski’s Truth Theorem - all have the flavor of some ancient fairy tale which warns you that “To seek self-knowledge is to embark on a journey which… will always be incomplete, cannot be charted on any map, will never halt, cannot be described.”
You work that you may keep pace with the earth and the soul of the earth.
For to be idle is to become a stranger unto the seasons,
and to step out of life's procession, that marches in majesty and proud submission towards the infinite.
When you work you are a flute through whose heart the whispering of the hours turns to music.
Which of you would be a reed, dumb and silent, when all else sings together in unison?
Always you have been told that work is a curse and labour a misfortune.
But I say to you that when you work you fulfil a part of earth's furthest dream, assigned to you when that dream was born,
And in keeping yourself with labour you are in truth loving life,
And to love life through labour is to be intimate with life's inmost secret.
But if you in your pain call birth an affliction and the support of the flesh a curse written upon your brow, then I answer that naught but the sweat of your brow shall wash away that which is written.
You have been told also that life is darkness, and in your weariness you echo what was said by the weary.
And I say that life is indeed darkness save when there is urge,
And all urge is blind save when there is knowledge,
And all knowledge is vain save when there is work,
And all work is empty save when there is love;
And when you work with love you bind yourself to yourself, and to one another, and to God.
And what is it to work with love?
It is to weave the cloth with threads drawn from your heart,
even as if your beloved were to wear that cloth.
It is to build a house with affection,
even as if your beloved were to dwell in that house.
It is to sow seeds with tenderness and reap the harvest with joy,
even as if your beloved were to eat the fruit.
It is to charge all things you fashion with a breath of your own spirit,
And to know that all the blessed dead
are standing about you and watching.
Often have I heard you say, as if speaking in sleep, "He who works in marble, and finds the shape of his own soul in the stone, is nobler than he who ploughs the soil.
And he who seizes the rainbow to lay it on a cloth in the likeness of man, is more than he who makes the sandals for our feet."
But I say, not in sleep but in the overwakefulness of noontide, that the wind speaks not more sweetly to the giant oaks than to the least of all the blades of grass;
And he alone is great who turns the voice of the wind into a song made sweeter by his own loving.
Work is love made visible.
And if you cannot work with love but only with distaste, it is better that you should leave your work and sit at the gate of the temple and take alms of those who work with joy.
For if you bake bread with indifference, you bake a bitter bread that feeds but half man's hunger.
And if you grudge the crushing of the grapes, your grudge distils a poison in the wine.
And if you sing though as angels, and love not the singing, you muffle man's ears to the voices of the day and the voices of the night.
On polarity and the non-linear nature of reality, inspiring "lifelong spiraling discovery and learning". From [[Tao: The Watercourse Way|http://www.wisdom2be.com/files/1b033e1855ea8cd5d7f40a4f1ff78ed1-120.html]] by Alan Watts: At the very roots of Chinese thinking and feeling there lies the principle of polarity, which is not to be confused with the ideas of opposition or conflict. In the metaphors of other cultures, light is at war with darkness, life with death, good with evil, and the positive with the negative, and thus an idealism to cultivate the former and be rid of the latter flourishes throughout much of the world. To the traditional way of Chinese thinking, this is as incomprehensible as an electric current without both positive and negative poles, for polarity is the principle that + and —, north and south, are different aspects of one and the same system, and that the disappearance of either one of them would be the disappearance of the system. People who have been brought up in the aura of Christian and Hebrew aspirations find this frustrating, because it seems to deny any possibility of progress, an ideal which flows from their linear (as distinct from cyclic) view of time and history. Indeed, the whole enterprise of Western technology is “to make the world a better place”—to have pleasure without pain, wealth without poverty, and health without sickness. But, as is now becoming obvious, our violent efforts to achieve this ideal with such weapons as DDT, penicillin, nuclear energy, automotive transportation, computers, industrial farming, damming, and compelling everyone, by law, to be superficially “good and healthy” are creating more problems than they solve. We have been interfering with a complex system of relationships which we do not understand, and the more we study its details, the more it eludes us by revealing still more details to study. As we try to comprehend and control the world it runs away from us. Instead of chafing at this situation, a Taoist would ask what it means. What is that which always retreats when pursued? Answer: yourself. Idealists (in the moral sense of the word) regard the universe as different and separate from themselves—that is, as a system of external objects which needs to be subjugated. Taoists view the universe as the same as, or inseparable from, themselves— so that Lao-tzu could say, “Without leaving my house, I know the whole universe.” This implies that the art of life is more like navigation than warfare, for what is important is to understand the winds, the tides, the currents, the seasons, and the principles of growth and decay, so that one’s actions may use them and not fight them. In this sense, the Taoist attitude is not opposed to technology per se. Indeed, the Chuang-tzu writings are full of references to crafts and skills perfected by this very principle of “going with the grain.” The point is therefore that technology is destructive only in the hands of people who do not realize that they are one and the same process as the universe. Our overspecialization in conscious attention and linear thinking has led to neglect, or ignorance, of the basic principles and rhythms of this process, of which the foremost is polarity.
A clear-eyed and utilitarian view by Sallustius (4^^th^^ century!), touching on the nature of reality, human nature, learning, and "the social (as well as personal) good (and good life :)" : >One may call the world a myth, in which bodies and things are visible, but souls and minds hidden. Besides, to wish to teach the whole truth about the Gods to all produces contempt in the foolish, because they cannot understand, and lack of zeal in the good, whereas to conceal the truth by myths prevents the contempt of the foolish, and compels the good to practice philosophy. :: -- from //Concerning myths; that they are divine, and why//.
Optimism is an occupational hazard of programming: feedback is the treatment.
In a book by Alan Burdick titled "Why Time Flies: A Mostly Scientific Investigation" (see [[the coverage at Brainpickings|https://www.brainpickings.org/2017/09/04/alan-burdick-why-time-flies-empathy/]] and my tiddler [[On confusing concepts with reality]]), he describes a lecture given by the German zoologist Karl Ernst von Baer in 1860, which would be fascinating to conduct/follow as a thought experiment: >Nothing lasts, von Baer told his audience. What we mistake for persistence -- the seeming permanence of mountains and seas -- is an illusion derived from our short lifespan. Imagine for a moment "that the pace of life in man were to pass much faster or much slower, then we would soon discover that, for him, all the relations of nature would appear entirely differently." Suppose a human's lifetime, from birth to senility, lasted just twenty-nine days, one-thousandth its normal length. >This ~Monaten-Mensch, or "man of the month," would never see the moon go through more than one full cycle; the concept of seasons and of snow and ice would be as abstract as the Ice Age is to us. The experience would be akin to that of many creatures, including some insects and mushrooms, that live for just a few days. Now suppose our lifespan were a thousand times shorter still and lasted just forty-two minutes. This ~Minuten-Mensch, or “man of minutes” would know nothing directly of night and day; flowers and trees would appear unchanging. (compare to what Daily Alice (Alice Dale Drinkwater) had to say about trees in the fantastic book "Little, Big": "Did you ever think, that maybe trees are alive like we are, only just more slowly? That what a day is to us, maybe a whole summer is to them - between sleep and sleep, you know. That they have long long thoughts and conversations that are just too slow for us to hear.") >Consider the opposite scenario, von Baer went on. Imagine that our pulse, instead of speeding up, were to be at a thousand times slower than its normal rate. If we assume the same amount of sensory experience per beat, "then the lifetime of such a person would reach a 'ripe old age' at approximately 80,000 years. A year would seem like 8.75 hours. We would lose our ability to watch ice melt, to feel earthquakes, to watch trees sprout leaves, slowly bear fruit and then shed leaves." We would see mountain ranges rise and fall but overlook the lives of ladybugs. Flowers would be lost on us; only trees would make an impression. The sun might leave a tail in the sky like that of a comet or a cannonball. It's worth [[comparing this to recent discoveries about "the hidden life of trees" and their seemingly "social" behavior|The intelligence of trees and the impact of time scales]] (and also put [[human life in perspective through size/time scales|Human life in perspective]]). >To some degree this is wordplay. If we define a day as a single rotation of Earth on its axis, then one day always lasts exactly one day to human, mite, and hazelnut alike. (A circadian biologist would point out that in fact the day is genetically inscribed in each of us, hazelnut to human, whether we're conscious of it or not.) Condillac's point, however, was that to the Mites of Hazelnut, one day may not be a useful, or even a perceptible, span of time. That thought contains a notion of time that is still very much in play today: our estimate of how long a moment seems to last is shaped by the number of actions or ideas that pass through the mind as the moment unfolds. "We have no perception of duration but by considering the train of ideas that take their turns in our understandings," John Locke argued in 1690. If you experience many sensations in a brief period, then that duration, being densely filled, will feel longer while you're in it. An instant may seem dimensionless to us, Locke wrote, yet there might be other minds capable of perceiving it and we could have no more awareness of them than "a worm shut up in one drawer of a cabinet hath of the senses or understanding of a man." Our mind, moving only so quickly, can hold only so many ideas at once, so there's a limit to the span of time we can perceive. "Were our senses altered, and made much quicker and acuter, the appearance and outward scheme of things would have quite another face to us." > >Now multiply this life a thousand more times, to produce a man living 80 million years but having just 31.5 heartbeats and 189 perceptions in one Earth year. The Sun would cease to appear as a discrete circle and would instead appear as a glowing solar elliptic, dimmer in winter. For ten pulse beats of the year Earth would be green, then white for ten more; snow would melt in a heartbeat and a half. > >Through the seventeenth and eighteenth centuries, the increasing use of the telescope and microscope led to consideration of what might be called the relativity of scales. The cosmos was bigger than imagined, in both directions; it blossomed both out and in. The human perspective began to lose its sense of privilege: our outlook might be just one of many. Suppose, the philosopher Nicolas Malebranche posited, in 1678, that God had created a world so vast that a single tree would appear enormous to us yet seem normal to that realm's inhabitants-or, conversely, a world that appears tiny to us yet yawns in the eyes of its minuscule residents. "Car rien n'est grand ni petit en soi," Malebranche Wrote; nothing is big or small in and of itself. Jonathan Swift soon captured the idea in a novel; the outlook of the Lilliputians and that of the giant Brobdingnagians are equivalent in their detail and expanse. > >So it is with time. "Imagine a world made up of as many parts as our own that was no bigger than a hazelnut," the French philosopher Etienne Bonnot de Condillac wrote in 1754. "It is beyond doubt that the stars would rise and set there thousands of times in one of our hours." Or imagine a world that dwarfs ours in its vastness: a lifespan in our world would seem but a flicker to the beings of that larger realm, while to residents of Planet Hazelnut our lives might last billions of years. The perception of duration is relative; a moment to one eye may be several to another. """ """ [time scale] [time horizon] [wicked environment] [kind environment]
The web annotation technology implemented for instance in [[Genius Web Annotator|http://genius.com/web-annotator]] or [[Hypothesis|https://github.com/hypothesis/h]] offers a great capability for knowledge building and sharing, and development of critical thinking.
See an example of annotating the poem [[Ozymandias by Percy Bysshe Shelley|http://genius.com/Percy-bysshe-shelley-ozymandias-annotated]]:
[>img[Ozymandias|./resources/Ozymandias.jpeg][./resources/Ozymandias.jpeg]]
I met a traveller from an antique land
Who said—"Two vast and trunkless legs of stone
Stand in the desert . . .Near them, on the sand,
Half sunk a shatter'd visage lies, whose frown,
And wrinkled lip, and sneer of cold command,
Tell that its sculptor well those passions read
Which yet survive, stamped on these lifeless things,
The hand that mocked them and the heart that fed;
And on the pedestal these words appear:
My name is Ozymandias, King of Kings;
Look on my works, ye mighty, and despair!
Nothing beside remains. Round the decay
Of that colossal wreck, boundless and bare,
The lone and level sands stretch far away."—
<html><p style="text-align:right">My name is Ozymandias, King of Kings; Look on my works, ye mighty, and despair!</p></html>
BTW, Shelley's friend and poet Horace Smith penned a competing (and not less evocative :) [[poem with the same name|http://www.potw.org/archive/potw192.html]] ("Ozymandias"):
In Egypt's sandy silence, all alone,
Stands a gigantic Leg, which far off throws
The only shadow that the Desert knows:—
"I am great OZYMANDIAS," saith the stone,
"The King of Kings; this mighty City shows
"The wonders of my hand."— The City's gone,—
Naught but the Leg remaining to disclose
The site of this forgotten Babylon.
We wonder,—and some Hunter may express
Wonder like ours, when thro' the wilderness
Where London stood, holding the Wolf in chace,
He meets some fragment huge, and stops to guess
What powerful but unrecorded race
Once dwelt in that annihilated place.
And referring to the content of Shelley's poem, I came across William Shakespeare's poem [[The Rape Of Lucrece|http://shakespeare.mit.edu/Poetry/RapeOfLucrece.html]], which is too, connected via a technology link: it was quoted in a seminal [[paper by Stuart Haber W. Scott Stornetta, titled "How to Time-Stamp a Digital Document"|https://www.anf.es/pdf/Haber_Stornetta.pdf]], basically laying down the foundation for the [[Blockchain technology|https://en.wikipedia.org/wiki/Blockchain]], which is at the heart of digital cryptocurrencies like Bitcoin.
The original idea of the Blockchain researchers (Haber and Stornetta from Bellcore, NJ) was the idealistic desire to find a way to secure the past and safeguard our knowledge of it. In other words, resist the ravages of time:
Time's glory is to calm contending kings,
To unmask falsehood and bring truth to light,
To stamp the seal of time in aged things,
To wake the morn and sentinel the night,
To wrong the wronger till he render right,
To ruinate proud buildings with thy hours,
And smear with dust their glittering golden towers;
To fill with worm-holes stately monuments,
To feed oblivion with decay of things,
To blot old books and alter their contents,
To pluck the quills from ancient ravens' wings,
To dry the old oak's sap and cherish springs,
To spoil antiquities of hammer'd steel,
And turn the giddy round of Fortune's wheel;
To those who say that we need weights and measures in order to enforce accountability in education, my response is, yes, of course we do, but only under three conditions that are not being met today. We need to make sure (1) that we measure things worth measuring in the context of authentic education, where rote learning counts for little; (2) that we know how to measure what we set out to measure; and (3) that we attach no more importance to measurable things than we attach to things equally or more important that elude our instruments. :― from his book //The Courage to Teach: Exploring the Inner Landscape of a Teacher's Life//
In her [[weekly column in the WSJ this week|https://www.wsj.com/articles/why-history-will-repay-your-love-1495755666]], [[Peggy Noonan|http://www.peggynoonan.com/]] writes: //For Memorial Day some thoughts on historical memory.// She is taking inspiration from historian David ~McCullough who said: Knowing the past is ‘a wonderful way to enlarge the experience of being alive’. Here are some of Mr. ~McCullough’s observations on history, as captured in his recent book "The American Spirit" (a collection of his speeches): * It is a story. And what is a story? Mr. ~McCullough, paraphrasing E.M. Forster, observes: "If I say to you the king died and then the queen died, that’s a sequence of events. If I say the king died and the queen died of grief, that’s a story." * What’s past to us was the present to them. * They were never certain of success. * Nothing had to happen the way it happened. * We make more of the wicked than the great. * America came far through trial and error. * History is an antidote to the hubris of the present. We think everything we have, do and think is the ultimate, the best. "We should never look down on those of the past and say they should have known better. What do you think they will be saving about us in the future? They’re going to be saying we should have known better." * Knowing history will make you a better person. Mr. ~McCullough endorses Samuel Eliot Morison’s observation that reading history improves behavior by giving examples to emulate. He quotes John Adams: "We can’t guarantee success [in the Revolutionary War], but we can do something better. We can deserve it." This contrasts, Mr. ~McCullough says, with current attitudes, in which success is all.
Just as there are odors that dogs can smell and we cannot, as well as sounds that dogs can hear and we cannot, so too there are wavelengths of light we cannot see and flavors we cannot taste. Why then, given our brains wired the way they are, does the remark "Perhaps there are thoughts we cannot think," surprise you? Evolution, so far, may possibly have blocked us from being able to think in some directions; there could be unthinkable thoughts. :: -- from [[Richard Hamming's "The Unreasonable Effectiveness of Mathematics"|resources/Hamming.html]] Or as [[Haldane|https://en.wikipedia.org/wiki/J._B._S._Haldane]] said: [[My own suspicion is that the universe is not only queerer than we suppose, but queerer than we can suppose... I suspect that there are more things in heaven and earth that are dreamed of, or can be dreamed of, in any philosophy.]] (see [[John Updike's thoughts|The mystery of being is a permanent mystery, at least given the present state of the human brain]] for a related perspective) (read [[More on unthinkable thoughts]] for more :) (see also [[Steven Weinberg's take on unification for simplicity|On unification for simplicity]]).
From an [[excellent, uplifting and down-to-earth talk|http://www.pbs.org/johngardner/sections/writings_speech_1.html]] by John Gardner on Personal Renewal. Key to self renewal are motivation/enthusiasm and interestedness (__not__ in the Dale Carnegie utilitarian way), or in his words: >Be interested. Everyone wants to be interesting – but the vitalizing thing is to be interested. Keep a sense of curiosity. Discover new things. Care. Risk failure. Reach out. A sense of context, commitment, and meaning are also very important: >As Robert Louis Stevenson said, "Old or young, we're on our last cruise." We want it to mean something. (compared to Shunryu Suzuki's "Life is like stepping onto a boat that is about to sail out to sea and sink.") > >For many this life is a vale of tears; for no one is it free of pain. But we are so designed that we can cope with it if we can live in some context of meaning. Given that powerful help, we can draw on the deep springs of the human spirit, to see our suffering in the framework of all human suffering, to accept the gifts of life with thanks and endure life's indignities with dignity. > >In the stable periods of history, meaning was supplied in the context of a coherent communities and traditionally prescribed patterns of culture. Today you can't count on any such heritage. You have to build meaning into your life, and you build it through your commitments -- whether to your religion, to an ethical order as you conceive it, to your life's work, to loved ones, to your fellow humans. Young people run around searching for identity, but it isn't handed out free any more -- not in this transient, rootless, pluralistic society. Your identity is what you've committed yourself to. > >It may just mean doing a better job at whatever you're doing. There are men and women who make the world better just by being the kind of people they are -- and that too is a kind of commitment. They have the gift of kindness or courage or loyalty or integrity. It matters very little whether they're behind the wheel of a truck or running a country store or bringing up a family. And also: >We tend to think of youth and the active middle years as the years of commitment. As you get a little older, you're told you've earned the right to think about yourself. But that's a deadly prescription! People of every age need commitments beyond the self, need the meaning that commitments provide. Self-preoccupation is a prison, as every self-absorbed person finally knows. Commitments to larger purposes can get you out of prison. And about optimism vs. pessimism: >I'd be a pessimist but it would never work. >I can tell you that for renewal, a tough-minded optimism is best. The future is not shaped by people who don't really believe in the future. Men and women of vitality have always been prepared to bet their futures, even their lives, on ventures of unknown outcome. If they had all looked before they leaped, we would still be crouched in caves sketching animal pictures on the wall. > >But I did say tough-minded optimism. High hopes that are dashed by the first failure are precisely what we don't need. We have to believe in ourselves, but we mustn't suppose that the path will be easy, it's tough. Life is painful, and rain falls on the just, and Mr. Churchill was not being a pessimist when he said "I have nothing to offer, but blood, toil, tears and sweat." He had a great deal more to offer, but as a good leader he was saying it wasn't going to be easy, and he was also saying something that all great leaders say constantly -- that failure is simply a reason to strengthen resolve. And he concludes: >Meaning is not something you stumble across, like the answer to a riddle or the prize in a treasure hunt. Meaning is something you build into your life. You build it out of your own past, out of your affections and loyalties, out of the experience of humankind as it is passed on to you, out of your own talent and understanding, out of the things you believe in, out of the things and people you love, out of the values for which you are willing to sacrifice something. The ingredients are there. You are the only one who can put them together into that unique pattern that will be your life. Let it be a life that has dignity and meaning for you. If it does, then the particular balance of success or failure is of less account. [[Maria Popova reviews John Gardner's writing on self-renewal|https://www.brainpickings.org/2014/07/14/self-renewal-gardner/]], and quotes him on the differences between renewal, innovation, and change: >Renewal is not just innovation and change. It is also the process of bringing the results of change into line with our purposes. When our forebears invented the motor car, they had to devise rules of the road. Both are phases of renewal. When urban expansion threatens chaos, we must revive our conceptions of city planning and metropolitan government. > >Mesmerized as we are by the idea of change, we must guard against the notion that continuity is a negligible — if not reprehensible — factor in human history. It is a vitally important ingredient in the life of individuals, organizations and societies. Particularly important to a society’s continuity are its long-term purposes and values. These purposes and values also evolve in the long run; but by being relatively durable, they enable a society to absorb change without losing its distinctive character and style. They do much to determine the direction of change. They insure a society will not be buffeted in all directions by every wind that blows. > >A sensible view of these matters sees an endless interweaving of continuity and change. >[…] >The only stability possible is stability in motion.
This is a good example of a school doing something important to [[teach students to skate to where the hockey puck is going to be|books/i4i/skating_puck_4.html]] (vs. just teaching to skate to where the puck currently is). And [[another article|http://www.greatschools.org/parenting/learning-development/5894-javascript-class-learn.gs]] in [[GreatSchools|http://www.greatschools.org/]] about the urgent need to be serious about teaching CS in school. But of course, Douglas Rushkoff, author of [[Program or Be Programmed|http://www.rushkoff.com/program-or-be-programmed/]] and evangelist for [[Codeacademy|Codeacademy.com]], is [[writing about it|http://www.rushkoff.com/blog/2012/1/16/cnn-why-i-am-learning-to-code-and-you-should-too.html]] a lot. In this article, titled [[Coding the Curriculum: How High Schools Are Reprogramming Their Classes|http://mashable.com/2013/09/22/coding-curriculum/]] in [[Mashable|http://mashable.com/]], Eric Larson writes about ''more than one school''^^1^^ introducing computation (he/they call it //coding//, but I like computation better, since it's closer to Computational Thinking, which is at the heart of what they (and I) are trying to enable). The idea in a nutshell: >The school isn't launching mandatory programming courses into the schedule, exactly, but is instead having its teachers introduce coding (ideally, in the most organic ways possible) into their respective subjects. Calculation-heavy courses such as math and science, as well as humanities such as English, Spanish and history -- even theater and music -- will all be getting a coded upgrade. At [[Beaver School|http://www.bcdschool.org/]] (grades 6-12), they are introducing computation into //every class//. And according to them, both faculty and students love it. They also got support from industry, backed up by [[data|http://code.org/stats]] regarding the need to step up CS and STEM education: >The private sector has for years been pressing sixth through twelfth grade schools to prepare kids earlier on for the tech-heavy workforce lying ahead of them. [[Code.org|http://code.org/stats]] reports more than 1.4 million computer jobs will be in demand by 2020, yet only 400,000 students will go on to study computer science in college. Even though introducing computing into the entire school curriculum was an idea brought up by one teacher (the head of the Math department), with the strong support of the principal, the faculty is fully supporting it: >Beaver's staff believes it's time to revamp the curriculum as a whole -- if only to better, and realistically, prepare its kids for the 21st century economy. The head of the math department: >"The old teaching method -- you know, where a teacher says something and you write it down and then take a test -- that's about as passive as it gets," he [the math teacher] says. "This idea [of Computation-enabled Curricula] pushes kids to be more actively involved since, by and large, it's something we're both learning together. That leads to a lot of innovative teaching -- and a lot of innovative learning, for that matter." And the principal: >"the current curriculum -- which any American who has gone to school in the last century is familiar with -- is blatantly outdated. Do schools need to change? Absolutely," he says. "We're still preparing our kids to go to work in 1988. Certainly not 2020." but >For some Beaver staff members -- especially those with no background in programming or math -- learning the language was an intimidating adjustment. and there is a psychological shift that needs to happen, regarding teacher/student knowledge/expertise: >Most of the staff recognizes that students might be better versed in programming than they are. But instead of being intimidated, [the math teacher] says, it's something they're embracing as a way to bring out a more two-sided-conversation approach in the classroom. "We don't get freaked out if we've got a student who's a better basketball player than the coach," [the math teacher] says. "A coach isn't failing if he's got a player who can dunk over him. In the same way, a teacher isn't failing just because he's got a student who might be able to code a little better." The principal also believes that introducing computation across the school has another benefit - it improves faculty relationships: >In addition to bringing students together, he [the principal] is optimistic it will strengthen relationships between teachers. A seventh grade science teacher and a tenth grade history teacher might not have much to talk about -- but with the new curriculum in place, conversations about coding workshops, Wiki ideas or digital shortcuts could be just as practical and relevant for a twelfth grade class as they are for a sixth grade class. And they have the right idea about not teaching every student to be a programmer, but >"We don't need to engineer a workshop so every kid that graduates here becomes a professional programmer," he [the principal] says. "We just want them to think about new ways to solve issues, and grasp that entrepreneurial mindset early on. It's ... it's just this day and age." ---- ^^1^^ - [[All of Chicago's Schools|http://www.huffingtonpost.com/2013/12/10/chicago-public-schools-co_n_4419916.html]] (2013) - [[NYC schools|http://www.johndeweyhighschool.org/academics/computer-science-institute/]], including [[20 pilot schools|http://schools.nyc.gov/Offices/mediarelations/NewsandSpeeches/2012-2013/AppliedSciences.htm]] (2013) - [[Schools in Maryland|http://www.mbhs.edu/departments/magnet/courses_cs.php]]
__Summary__: I have changed my mind about the general validity of the mechanical worldview that underlies the modern scientific understanding of natural processes. ''Goodwin writes:'' What is often suggested as an explanation of this [the "explanation" of qualitative experience in humans and other organisms.] is evolutionary complexity: When an organism has a nervous system of sufficient complexity, subjective experience and feelings can arise. This implies that something totally new and qualitatively different can emerge from the interaction of "dead/' unfeeling components such as cell membranes, molecules, and electrical currents. But this implies getting something from nothing, which violates what I have learned about emergent properties: There is always a precursor property for any phenomenon, and you cannot just introduce a new dimension into the phase space of your model to explain the result. Qualities are different from quantities and cannot be reduced to them. So what is the precursor of the subjective experience that evolves in organisms? One possibility is to acknowledge that the world isn't what modern science assumes it to be mechanical and "dead" but that everything has some basic properties relating to experience or feeling. Philosophers and scientists have been down this route before and call this view pan-sentience or panpsychism: the idea that the world is impregnated with some form of feeling in every one of its constituents. This makes it possible for complex organized beings, such as organisms, to develop feelings and for qualities to be as real as quantities. """ """ ''My observations/comments:'' This sounds mystical. While I tend to agree that "sufficiently complex" systems may tend to show emergent properties that may seem to be "wonderous", I don't think that they are a case of "getting something from nothing", as Goodwin says. I think that people tend to "project", "attribute", or anthropomorphize these kinds of emergent behaviors, and if this is what Goodwin calls "introducing a new dimension", then I agree with his objection, that you can't (and shouldn't) do this. But, I don't think that adopting a view of "pan-sentience", as Goodwin calls it, is necessary nor constructive (as a explanatory tool or model of reality). [[Douglas Hofstadter|Douglas Hofstadter]] has a [ext[vivid example (called "leafishness")|./resources/Hofstadter-leafishness-diSessa.jpg]] of inventing such an "entity" (i.e., "pan-sentience"), and it's quite striking to compare and contrast the two views.
__Summary:__ Like many people, I once . . . imagined there were real boundaries between the natural and the artificial, between one species and another, and thought that with the advent of genetic engineering we would be tinkering with life at our peril. I now believe that this romantic view of nature is a stultifying and dangerous mythology. ''Harris writes:'' The fossil record suggests that individual species survive, on average, between one million and ten million years. The concept of a "species" is misleading, however, and it tempts us to think that we, as Homo sapiens, have arrived at some well-defined position in the natural order. The term "species" merely designates a population of organisms that can interbreed and produce fertile offspring; it cannot be aptly applied to the boundaries between species (to what are often called "intermediate" or "transitional" forms). There was, for instance, no first member of the human species, and there are no canonical members now. Life is a continuous flux. Our nonhuman ancestors bred, generation after generation, and incrementally begat what we now deem to be the species Homo sapiens ourselves. There is nothing about our ancestral line or our current biology that dictates how we will evolve in the future. Nothing in the natural order demands that our descendants resemble us in any particular way. Very likely, they will not resemble us. We will almost certainly transform ourselves, likely beyond recognition, in the generations to come. ''My thoughts/comments:'' I agree with Harris that species as well as other concepts we coin are somewhat arbitrary, and are our way to "put a grid on top of reality" which is in flux and with no clear boundaries by nature. ''Harris writes:'' But what is the alternative to our taking charge of our biological destiny? Might we be better off just leaving things to the wisdom of nature? I once believed this. But we know that nature has no concern for individuals or for species. Those that survive do so despite her indifference. While the process of natural selection has sculpted our genome to its present state, it has not acted to maximize human happiness, nor has it necessarily conferred any advantage upon us beyond the ability to raise the next generation to child-bearing age. ''My thoughts/comments:'' I don't think that we should either "leave things to the wisdom of nature" or "take charge of our biological destiny", since it's not black and white, and the risks and rewards are potentially enormous, and therefore should be carefully and deeply considered. I find it striking that Harris acknowledges that things are in flux, and that nothing dictates how we will evolve in the future (I agree, and in my mind it's both because there are no guides/monitors/gods/nature/powers/etc., but also no way to know/predict/foretell the future), and yet, he boldly states that we should take charge of our own destiny (!) How can you do that, if you don't know what it is? And if you agree that you don't know, whouldn't it be advisable/prudent to take steps cautiously, with a lot of small steps and refinements, etc.? ''Harris writes:'' But our environment and our needs-to say nothing of our desires have changed radically in the meantime. We are in many respects ill-suited to the task of building a global civilization. This is not a surprise. From the point of view of evolution, much of much of human culture, along with its cognitive and emotional underpinnings, must be epiphenomenal. Nature cannot "see" most of what we are doing, or hope to do, and has done nothing to prepare us for many of the challenges we now face. ...Considering humanity as a whole, there is nothing about natural selection that suggests our optimal design. We are probably not even optimized for the Paleolithic, much less for life in the twenty-first century. And yet we are now acquiring the tools that will enable us to attempt our own optimization. Many people think this project is fraught with risk. But is it riskier than doing nothing? There may be current threats to civilization that we cannot even perceive, much less resolve, at our current level of intelligence. Could any rational strategy be more dangerous than following the whims of nature? This is not to say that our growing capacity to meddle with the human genome couldn't present some moments of Faustian overreach. But our fears on this front must be tempered by a sober understanding of how we got here. Mother Nature is not now, nor has she ever been, looking out for us. ''My thoughts/comments:'' Again, we shouldn't look at this as all-or-nothing. The "meddle with the human genome" is something that on our evolutionary path (by definition!), but should be done carefully and wisely, not out of fear/desperation that since "mother nature is not looking out for us, we should accept 'Faustian overreaches'.
Andy Clark is a philosopher and cognitive scientist, University of Edinburgh; author, //Supersizing the Mind: Embodiment, Action, and Cognitive Extension// From [[my previous exposure to Clark|Natural-Born Cyborgs: Minds, Technologies, and the Future of Human Intelligence]], it looks like he is interested in "extensions to the human mind" and what he calls "intelligence amplifiers". This is definitely an area that excites me, and what I see as very relevant to the area of [[Human Performance Support|Human Performance Support]]. As [[I had said elsewhere|http://ldtprojects.stanford.edu/~hmark/]]: >There are opportunities at which timely access to relevant and multi-faceted knowledge and perspectives can be very powerful. >I strongly believe that technology affords and sometimes even creates these opportunities, and as such, is a great enabler of learning, and a powerful booster of human potential, significantly enhancing both knowledge and skills, propelling us beyond our natural, evolutionary trajectory. Clark is asking: if the question is "is the internet changing the nature of our thinking?", i.e., is our thinking being (or will our thinking in the future be) radically transformed, ''how will we know?'' >Suppose we convince ourselves, by whatever means, that as far as the basic mode of operation of the brain goes, Internet experience is not altering it or one whit. That supports a negative answer only if we assume that the routines that fix the "nature of human thinking" must be thoroughly biological that they must be routines running within, and only within, the individual human brain. But surely it is this assumption that our experiences with the Internet (and with other "intelligence amplifiers" before it) most clearly call into question. Perhaps the Internet is changing "the way you think" by changing the circuits that get to implement some aspects of human thinking, providing some hybrid (biological and non-biological) circuitry for thought itself. This would be a vision of the Internet as a kind of worldwide supracortex. Since this electronic supracortex patently does not work according to the same routines as, say, the neocortex, an affirmative answer to our target question seems easily in the cards. But he cautions us not to jump to conclusions: "this may turn out to be a deep illusion)". >For perhaps one way to motivate an answer is to look for deep and systematic variation in human p performances in various spheres of thought. But even if we find such variation, those who think that our "ways of thinking" remain fundamentally unaltered can hold their ground by stressing that the basic mode of neural operation is unaltered and has remained the same for (at least) tens of thousands of years. And he concludes: >Deep down, I suspect that our two interrogative options the trivial-sounding question about what we think and the deep-sounding one about the nature of our thinking are simply not as distinct as the fans of either response (Yes, the Internet is changing the way we think/No, it isn't) might wish. But I don't know how to prove this. Dammit. My sense is similar: I think that there is a ''bi-directional interaction and influence'' between //what// we think (the trivial/dumb interpretation of the question, per Clark), and //how// we think about what we think (the kinds of algorithms or computational recipes for solving problems). It reminds me of [[an example Andrea diSessa gives|resources/diSessa - Changing Minds - Chapter1.pdf]] about the __power of literacy__ to change the way we think: One example is the Calculus, a new notation (Newton, Leibniz) that forever changed not only what we think but also how we think about change (infinitesimal deltas) and rations of changes. And not only did it change how we are thinking, but also who and when: nowadays, high school students can think and express their thinking in ways that very sharp scientists (Galileo comes to mind) could not in the past. Another example diSessa gives is how it takes Galileo several pages of text to describe his idea about rates of changes staying constant (in a free fall, related to his experiment at the Tower of Pisa), and the fact that nowadays, a high school student can express the //same ideas// in a few lines of "very simple" (high school) math. It seems to me that the fact that a genius like Galileo had to struggle through pages of explanations in order to make //his ideas and way of thinking// clear (to himself and others), and something today a high school kid can both grasp, express, and use, shows us that "external intelligence amplifiers" can and do change the way we think. And if Computation in general (and the Internet in particular) cannot serve as such an "amplifier", what can?
Thomas Metzinger is a philosopher; director of the Theoretical Philosophy Group at the Department of Philosophy of the Johannes Gutenberg-Universitdt Mainz; author of //The Ego Tunnel// >Sure, for academics the Internet is a fantastic resource...Something that is changing us in our deepest core... >But it's about much more than cognitive style alone. For those of us intensively working with it, the Internet has become a part of our self-model. We use it for external memory storage, as a cognitive prosthesis, and for emotional autoregulation. We think with the help of the Internet, and it helps us determine our desires and goals. Affordances infect us, subtly eroding the sense of control. We are learning to multitask, our attention span is becoming shorter, and many of our social relationships are taking on a strangely disembodied character, Some software tells us, "You are now friends with Peter Smith!" when we were just too shy to click the Ignore button. >The core of the problem is not cognitive style but attention management. The ability to attend to our environment, our feelings, and the feelings of others is a naturally evolved feature of the human brain. Attention is a finite commodity, and it is absolutely essential to living a good life. We need attention in order to truly listen to others and even to ourselves. We need attention to truly enjoy sensory pleasures, as well as for efficient learning. We need it in order to be truly present during sex, or to be in love, or when we are just contemplating nature. Our brains can generate only a limited amount of this precious resource every day. Today the advertisement and entertainment industries are attacking the very foundations of our capacity for experience, drawing us into a vast and confusing media jungle, robbing us of our scarce resource in ever more persistent and intelligent ways. We know all that, but here's something we are just beginning to understand: The Internet affects our sense of selfhood. and it does so on a deep functional level.
__Summary: __When reporters interviewed me in the 1970s and '80s about the possibilities for Artificial Intelligence I would always say that we would have machines as smart as we are within my lifetime. . . . I no longer believe that will happen. !!!Schank has some good points about why our approach to AI has been "wrongheaded": * Early AI workers sought out intelligent behaviors to focus on like chess or problem solving and tried to build machines that could equal human beings in those endeavors. While this was an understandable approach, it was, in retrospect, wrongheaded. Chess playing is not really a typical intelligent human activity. Only some of us are good at it, and it seems to entail a level of cognitive processing that, while impressive, seems quite at odds with what makes humans smart. Chess players are methodical planners. Human beings are not. * We tend to not know what we know. We can speak properly without knowing how we do it. We don't know how we comprehend. We just do. All this poses a problem for AI. How can we imitate what humans are doing when humans don't know what they're doing when they do it? * This conundrum led to a major failure in AI expert systems, which relied on rules that were supposed to characterize expert knowledge. But, the major characteristic of experts is that they get faster when they know more, whereas more rules made systems slower. The idea that rules w were not at the center of intelligent systems meant that the flaw was relying on specific consciously stated knowledge instead of trying to figure out what people meant when they said they just knew it when they saw it, or they had a gut feeling. People give reasons for their behaviors, but they are typically figuring that stuff out after the fact. We reason non-consciously and explain rationally later. ''My thoughts/comments:'' * Schank's point about picking [[chess playing|History of the chess table]] as a sign of intelligence shows how [[our understanding evolves over time|The end of an era, the beginning of another? HAL, Deep Blue and Kasparov]], and as we acquire new knowledge/experience. Back in the day when computers could not play chess well (and very few people thought they ever will), it was a "worthwhile" challenge, and it embodied a certain image of ourselves as humans: analytical, rational, planning, etc. Nowadays, as Schank points out, technology caught up (we "threw hardware at the problem": IBM's Deep Blue had 32, 32-bit, parallelly processing CPUs, 512 "chess processors", 1 Trillion Floating Operations per second)), it's no longer a big challenge, ''and'' our image of ourselves has evolved. * [[Many people (neuro-scientists among them)|The chess mentality]] may still think that playing chess well is a human characteristic ([["the chess mentality... Humanity wouldn't be human (or humane) without it."|http://www.research.ibm.com/deepblue/learn/html/e.8.4.html]]). Schank is stating that "Chess playing is not really a ''typical'' intelligent human activity", and I tend to agree with him. * it's interesting to compare to a later challenge and project by IBM: a computer called Watson, playing (and beating the "world master" of) Jeopardy. Is this "the new definition of intelligence?" * The point about Expert Systems (ESs) codifying knowledge in the form of rules, where more "expertise" actually slows down the ES, which is counter to the human trend, reminds me of a similar train of thought (and epiphany, or at least a "warning sign" about the misguided direction) Jeff Hawkins expresses in his excellent book ''On Intelligence'' (published in 2004). [[Hawkins wanted to apply to MIT and study/research AI in their graduate program|01 - Artificial Intelligence]]. But the prevailing approach in that department raised a red flag for him (it was a mutual feeling: he wanted to study the human brain/mind and learn from it about (artificial) intelligence; they were not interested. He was not admitted to the program). * A popular misconception/assumption about chess, which got debunked, from a paper by Anders Ericsson [[The Making of an Expert|http://www.uvm.edu/~pdodds/files/papers/others/everything/ericsson2007a.pdf]]: > Thirty years ago, two Hungarian educators, Laszlo and Klara Polgar, decided to challenge the popular assumption that women don't succeed in areas requiring spatial thinking, such as chess. They wanted to make a point about the power of education. The Polgars homeschooled their three daughters, and as part of their education the girls started playing chess with their parents at a very young age. Their systematic training and daily practice paid off. By 2000, all three daughters had been ranked in the top ten female players in the world. The youngest, Judit, had become a grand master at age 15, breaking the previous record for the youngest person to earn that title, held by Bobby Fischer, by a month. Today Judit is one of the world's top players and has defeated almost all the best male players.
From the [[book "Is the Internet Changing the Way You Think?"|Is the Internet Changing the Way You Think?]] An interesting analogy between different ways of boat building and different learning (and performance) modes by George Dyson - Science historian; author of Darwin Among the Machines. >In the North Pacific, there were two approaches to boatbuilding. The Aleuts and their kayak-building relatives lived on barren, treeless islands and built their vessels by piecing together skeletal frameworks from fragments of beachcombed wood. The Tlingit and their dugout-canoe-building relatives built their vessels by selecting entire trees out at of the rain forest and removing wood until there was nothing left but a canoe. >The Aleut and the Tlingit achieved similar results maximum boat, minimum material by opposite means. The flood of information unleashed by the Internet has produced a similar cultural split. We used to be kayak builders, collecting all available fragments of information to assemble the framework that kept us afloat. Now we have to learn to become dugout-canoe builders, discarding unnecessary information to reveal the shape of knowledge hidden within. >I was a hardened kayak builder, trained to collect every available stick. I resent having to learn the new skills. But those who don't will be left paddling logs, not canoes. As there are entirely different skills needed to build a Canoe vs. a Kayak, so there are entirely different (or at least different enough) and new skills to learn and practice for learning, performing, and thriving in the Internet-enabled world. It will be critical to teach/learn skills such as prioritizing, organizing, visualizing, analogyzing, __verifying__, etc., working with vast sets of data. These skills have always been important to learn, but the lake has turned into an ocean (to play on the boating metaphor), and this makes at least a quantitative difference, but I think a qualitative one as well.
[[Sam Harris|http://en.wikipedia.org/wiki/Sam_Harris_%28author%29]] brings up a few significant ways in which the Internet has impacted him: * Since more and more information and data are online, he relies more and more on the Internet to recall his own thoughts. Not only that, but if a debate he is involved in is videotaped (sorry for the old-fashioned term) and posted on YouTube, he watches the debate online >for my memory of what happened is often at odds with the later impression I form based upon seeing the exchange. Which view is closer to reality? I have learned to trust the YouTube version. In any case, it is is the only one that will endure. * He also uses the Internet to shamelessly plagiarize himself, by recycling content from lectures into op-eds, and from there into books quoted in new lectures, and __so the spiral goes...__ *He found that searching his "bitstream, I am reminded not only of what I used to know but also of what I never properly understood. He concludes: >I am by no means infatuated with computers. I do not belong to any social networking sites; I do not tweet (yet); and I do not post images to Flickr. But even in my case, an honest response to the Delphic admonition "Know thyself" already requires an Internet search. I find myself in a similar situation, where since "more stuff" is easily/instantly available and searchable, it enables much richer exploration and deeper introspection/reflection, as well as generation of new insights, ideas, connections, and, again, __so the spiral goes...__
__Summary: __ I've changed my mind about how to handle the homunculus temptation: the almost irresistible urge to install a "little man in the brain" to be the Boss, the Central Meaner, the Enjoyer of pleasures, and the Sufferer of pains. !!Dennett describes top-down decomposition of a task into a hierarchical computer program The AI programmer begins with an intentionally characterized problem, and thus frankly views the computer anthropomorphically: if he solves the problem he will say he has designed a computer than can [e.g.,] understand questions in English. His first and highest level of design breaks the computer down into subsystems, each of which is given intentionally characterized tasks; he composes a flow chart of evaluators, rememberers, discriminators, overseers and the like. These are homunculi with a vengeance. . . . Each homunculus in in turn is analyzed into smaller homunculi, but, more important, into less clever homunculi. When the level is reached where the homunculi are no more than adders and subtractors, by the time they need only intelligence to pick the larger of two numbers when directed to, they have been reduced to functionaries "who can be replaced by a machine." ''My comments/thoughts:'' * This top-down deconstruction seems to me, shows that at least in theory, every task, even the most complex (and human?) one, can be broken into simple/basic operations, and thus links "intelligent behavior/tasks" to very basic/mechanical operations, without requiring "magic" (soul?). * This reminds me of a book on Cellular Automata (CA) [Steven Levy's book Artificial Life, the quest for a new creation ] that showed how a simple Reduced Instruction Set Computer (RISC) can be constructed with ~The-Game-Of-life-like rules on a [[Game Of Life|Cellular Automaton Rule 110]] 2-dimensional grid. Granted a RISC is not showing very intelligent behavior, ''and'' the CA to achieve even this behavior is pretty big, but it definitely shows the feasibility and validity of this approach.
Alison Gopnik - Psychologist, University of California, Berkeley; author, The Philosophical Baby: What Children's Minds Tell Us About Truth, Love, and the Meaning of Life Gopnik gives a though provoking analogy between the impact of Internet as a recent technology claimed to "change everything" and another less recent "technology" (and [[she also relates to this elsewhere too|The potential and dangers of new technologies - echoes of a recurring theme]]): >My thinking has certainly been transformed in alarming ways by a relatively recent information technology, but it's not the Internet. I often sit for hours in the grip of this compelling medium, motionless and oblivious, instead of interacting with the people around me. As I walk through the streets, I compulsively check out even trivial messages (movie ads, street signs), and I pay more attention to descriptions of the world (museum captions, menus) than to the world itself. I've become incapable of using attention and memory in ways that previous generations took for granted. > >Yes, I know, reading has given man a powerful new sources of information. But is it worth the isolation, or the damage to dialog and memorization that Socrates foresaw? Studies show, in fact, that we've become involuntarily compelled to read; I can't keep myself from decoding letters. Reading has even reshaped my brain: Cortical areas that once were devoted to vision and speech have been hijacked by print. Instead of learning through practice and apprenticeship, I've become dependent on lectures and textbooks. And look at the toll of dyslexia and attention disorders and learning disabilities all signs that our brains were not designed to deal with such a profoundly unnatural technology. Historically, reading may have been feared by some as "degrading our human abilities" (oration, memory, etc.) (see [[Plato's/Socrates' opinions|Why writing (and the computer :) is a 'dangerous technology']]), promoting a-social behavior (isolation, self-absorption, due to "curling up with a good book"), etc. But, we can't conceive of our lives without mastery of reading. So it'll be interesting to see how the internet impacts our lives, and how real the concerns and perceived threats from it really materialize. BTW, Hermann Hesse wrote a [[thought provoking essay about three types of readers|Hermann Hesse on Three Types of Readers]] which is relevant to this.
>__Summary:__ I've come to reject the common SETI (search for extraterrestrial intelligence) wisdom that there must be millions of technology-capable civilizations within our "light sphere" (the region of the universe accessible to us by electromagnetic communication). Ray Kurzweil mentions [[Frank Drake's formula/equation|Interdisciplinary knowledge in an equation]] (as opposed to [[The Flake Equation]] :) for estimating the number of intelligent civilizations in a galaxy or in the universe. "Essentially, the likelihood of a planet evolving biological life that has created sophisticated technology is tiny, but there are so many star systems that there should still be many millions of such civilizations. Carl Sagan's^^1^^ analysis of the Drake formula concluded that there should be around a million civilizations ..." Yet we haven't detected the presence of any of these intelligent civilizations, hence the famous question [[Enrico Fermi|http://en.wikipedia.org/wiki/Enrico_Fermi]] raised: ''Where is everybody?'', also known as [[the Fermi Paradox|http://en.wikipedia.org/wiki/Fermi_paradox]] and [[possible solutions to the paradox|http://www.nss.org/resources/books/non_fiction/NF_023_whereiseverybody.html]]^^''2''^^. ''And Kurzweil's answer'': >My own conclusion is that they don't exist. If it seems unlikely that we would be in the lead in the universe, here on the third planet of a humble star in an otherwise undistinguished galaxy, it's no more perplexing than the existence of our universe, with its ever so precisely tuned formulas to allow life to evolve in the first place. This reminds me of a very vivid [[thought experiment involving coin flips|The "astonishing skills" of a coin flipper]], that demonstrates how a reversed way of thinking about cause and effect can lead to "astonishing" conclusions. (see also [[the anthropic principle|http://en.wikipedia.org/wiki/Anthropic_principle]])^^3^^. In the flipping coins experiment, if you look at the winner with the perfect score, without taking into account the way s/he has been selected, then this winning streak looks absolutely amazing. But this is due to a flaw in the logic. Similarly, if you look at our civilization, its state of technology and how we got here (similar to looking at the "amazingly skilled" winner of the coin flips experiment), you can draw the conclusion that there must be many other civilizations which are either equally or far more advanced than we are, and we should definitely hear/see them. But then again: where are they? In [[another article|http://www.kurzweilai.net/the-intelligent-universe]] Kurzweil is stating his reasons for why SETI will fail to find other intelligent civilizations/beings: !!!!Why SETI will fail >I'll end with a comment about the SETI project. Regardless of this ultimate resolution of this issue of the speed of light and it is my speculation (and that of others as well) that there are ways to circumvent it if there are ways, they'll be found, because intelligence is intelligent enough to master any mechanism that is discovered. Regardless of that, I think the SETI project will fail it's actually a very important failure, because sometimes a negative finding is just as profound as a positive finding for the following reason: we've looked at a lot of the sky with at least some level of power, and we don't see anybody out there. > >The SETI assumption is that even though it's very unlikely that there is another intelligent civilization like we have here on Earth, there are billions of trillions of planets. So even if the probability is one in a million, or one in a billion, there are still going to be millions, or billions, of life-bearing and ultimately intelligence-bearing planets out there. > >If that's true, they're going to be distributed fairly evenly across cosmological time, so some will be ahead of us, and some will be behind us. Those that are ahead of us are not going to be ahead of us by only a few years. They're going to be ahead of us by billions of years. But because of the exponential nature of evolution, once we get a civilization that gets to our point, or even to the point of Babbage, who was messing around with mechanical linkages in a crude 19th century technology, it's only a matter of a few centuries before they get to a full realization of nanotechnology, if not femto and pico-engineering, and totally infuse their area of the cosmos with their intelligence. It only takes a few hundred years! > >So if there are millions of civilizations that are millions or billions of years ahead of us, there would have to be millions that have passed this threshold and are doing what I've just said, and have really infused their area of the cosmos. Yet we don't see them, nor do we have the slightest indication of their existence, a challenge known as the Fermi paradox. Someone could say that this "silence of the cosmos" is because the speed of light is a limit, therefore we don't see them, because even though they're fantastically intelligent, they're outside of our light sphere. Of course, if that's true, SETI won't find them, because they're outside of our light sphere. > >But let's say they're inside our light sphere, or that light isn't a limitation, for the reasons I've mentioned. Then perhaps they decided, in their great wisdom, to remain invisible to us. You can imagine that there's one civilization out there that made that decision, but are we to believe that this is the case for every one of the millions, or billions, of civilizations that SETI says should be out there? > >That's unlikely, but even if it's true, SETI still won't find them, because if a civilization like that has made that decision, it is so intelligent they'll be able to carry that out, and remain hidden from us. Maybe they're waiting for us to evolve to that point and then they'll reveal themselves to us. Still, if you analyze this more carefully, it's very unlikely in fact that they're out there. > >You might ask, isn't it incredibly unlikely that this planet, which is in a very random place in the universe and one of trillions of planets and solar systems, is ahead of the rest of the universe in the evolution of intelligence? Of course the whole existence of our universe, with the laws of physics so sublimely precise to allow this type of evolution to occur is also very unlikely, but by the anthropic principle, we're here, and by an analogous anthropic principle we are here in the lead. After all, if this were not the case, we wouldn't be having this conversation. So by a similar anthropic principle we're able to appreciate this argument. ---- ^^1^^ An [[inspiring video clip|http://vimeo.com/channels/staffpicks/2822787]] with Sagan's voice-over, where he actually does not refer to other civilizations, but rather talks about the uniqueness and preciousness of our human life on this [[pale blue dot|http://vimeo.com/channels/staffpicks/2822787]] (on Vimeo) ^^2^^ The book //Where Is Everybody? Fifty Solutions to the Fermi Paradox// by Stephen Webb. See also the [[book review by David Brandt-Erichsen|http://www.nss.org/resources/books/non_fiction/NF_023_whereiseverybody.html]] of the National Space Society. ^^3^^ See [[Nick Bostrom|http://www.nickbostrom.com/]] on the [[anthropic principle|http://www.anthropic-principle.com/?q=book/table_of_contents]]
From the book [[Philosophy: An Introduction to the Art of Wondering|https://en.wikipedia.org/wiki/Philosophy:_An_Introduction_to_the_Art_of_Wondering]] by James L. Christian:
{{
The following pages may
lead you to wonder.
That’s really what philosophy
is—wondering.
To philosophize
is to wonder about life—
about right and wrong,
love and loneliness, war and death.
It is to wonder creatively
about freedom, truth, beauty, time
and a thousand other things.
To philosophize is
to explore life.
It especially means breaking free
to ask questions.
It means resisting
easy answers.
To philosophize
is to seek in oneself
the courage to ask
painful questions.
But if, by chance,
you have already asked
all your questions
and found all the answers—
if you’re sure you know
right from wrong,
and whether God exists,
and what justice means,
and why we mortals fear and hate and pray—
if indeed you have completed your wondering
about freedom and love and loneliness
and those thousand other things,
then the following pages
will waste your time.
Philosophy is for those
who are willing to be disturbed
with a creative disturbance.
Philosophy is for those
who still have the capacity
for wonder.
From her [[poem Possibilities, as printed and read at BrainPickings|https://www.brainpickings.org/2015/03/18/amanda-palmer-wislawa-szymborska-possibilities-poem-reading/]]:
(Translated by Stanislaw Baranczak and Clare Cavanagh)
```
I prefer movies.
I prefer cats.
I prefer the oaks along the Warta.
I prefer Dickens to Dostoyevsky.
I prefer myself liking people
to myself loving mankind.
I prefer keeping a needle and thread on hand, just in case.
I prefer the color green.
I prefer not to maintain
that reason is to blame for everything.
I prefer exceptions.
I prefer to leave early.
I prefer talking to doctors about something else.
I prefer the old fine-lined illustrations.
I prefer the absurdity of writing poems
to the absurdity of not writing poems.
I prefer, where love’s concerned, nonspecific anniversaries
that can be celebrated every day.
I prefer moralists
who promise me nothing.
I prefer cunning kindness to the over-trustful kind.
I prefer the earth in civvies.
I prefer conquered to conquering countries.
I prefer having some reservations.
I prefer the hell of chaos to the hell of order.
I prefer Grimms’ fairy tales to the newspapers’ front pages.
I prefer leaves without flowers to flowers without leaves.
I prefer dogs with uncropped tails.
I prefer light eyes, since mine are dark.
I prefer desk drawers.
I prefer many things that I haven’t mentioned here
to many things I’ve also left unsaid.
I prefer zeroes on the loose
to those lined up behind a cipher.
I prefer the time of insects to the time of stars.
I prefer to knock on wood.
I prefer not to ask how much longer and when.
I prefer keeping in mind even the possibility
that existence has its own reason for being.
```
There is an interesting phenomenon (an emerging phenomenon, or is it just a coincidence?) between the prime numbers and how they are represented/written, and a pattern that reveals itself. As [[the Wikipedia page|https://en.wikipedia.org/wiki/Ulam_spiral]] introduces it: >The Ulam spiral or prime spiral is a graphical depiction of the set of prime numbers, devised by mathematician Stanislaw Ulam in 1963 and popularized in Martin Gardner's Mathematical Games column in Scientific American a short time later. It is constructed by writing the positive integers in a square spiral and specially marking the prime numbers. > >Ulam and Gardner emphasized the striking appearance in the spiral of prominent diagonal, horizontal, and vertical lines containing large numbers of primes. Both Ulam and Gardner noted that the existence of such prominent lines is not unexpected, as lines in the spiral correspond to quadratic polynomials, and certain such polynomials, such as Euler's prime-generating polynomial x^^2^^ − x + 41, are believed to produce a high density of prime numbers. Or, as [[David Darling describes it|https://www.daviddarling.info/encyclopedia/U/Ulam_spiral.html]]: >The Ulam spiral is a remarkable geometric pattern accidentally found among the prime numbers by Stanislaw Ulam; it is also known as the prime spiral. During a boring meeting one day in 1963, Ulam drew a square, marked the number 1 at the center, and then wrote the increasing whole numbers as spiral that wound its way out to the edge of the paper. He then circled all the prime numbers and was immediately struck by how they tended to fall on diagonal lines radiating from the central 1. > >In Ulam's words the arrangement of primes "appears to exhibit a strongly nonrandom appearance." Ulam rushed home and expanded the spiral to cover a much larger portion of the number sequence. The strange pattern persisted. Primes had a tendency to occur in clusters and all clusters tended to make a beautiful image that couldn't be predicted. With the help of computers this pattern can now be explored almost indefinitely and it reveals a wonderfully rich combination of symmetry and surprise – very reminiscent of some fractals. The Ulam spiral is constructed by writing the positive integers in a spiral arrangement on a square lattice, and then marking the prime numbers: <a href="./resources/ulam1_360.png" target="new"><img src="./resources/ulam_output.png" width="100%" height="100%" /></a> The spiral above starts with 1 and grows/circles from there. As you can see there are some short diagonal lines that some of these primes (colored red) form. But these diagonals/lines are pretty short. If, instead we start with 41 and spiral from there, we can see longer diagonals, and in particular a top-right to bottom-left line of primes: <a href="./resources/ulam_long_diagonal.png" target="new"><img src="./resources/ulam_long_short.png" width="100%" height="100%" /></a> Here is a [[Python program|https://trinket.io/python/64d542a4e6]] which produces different Ulam Spirals, depending on how one configures the initial settings. """ """ There is an interesting link between Ulam's Spiral and what Arthur C. Clarke describes (7 years earlier!) as "a whirlpool of numbers". As [[Darling concludes|https://www.daviddarling.info/encyclopedia/U/Ulam_spiral.html]]: > The Ulam spiral should perhaps be known as the "Clarke spiral" in view of the fact that Arthur C. Clarke described the phenomenon in his novel The City and the Stars (1956, Ch. 6, p. 54),2 predating Ulam's discovery by several years. Clarke wrote: > >>Jeserac sat motionless within a whirlpool of numbers. The first thousand primes... Jeserac was no mathematician, though sometimes he liked to believe he was. All he could do was to search among the infinite array of primes for special relationships and rules which more talented men might incorporate in general laws. He could find how numbers behaved, but he could not explain why. It was his pleasure to hack his way through the arithmetical jungle, and sometimes he discovered wonders that more skillful explorers had missed. He set up the matrix of all possible integers, and started his computer stringing the primes across its surface as beads might be arranged at the intersections of a mesh.
In an article titled [[Procedural Literacy: Educating the New Media Practitioner|http://press.etc.cmu.edu/node/205]] by Michael Mateas, he talks about the discussion between CS Luminaries Alan Perlis, J. C. R. Licklider, and Peter Elias. Perlis clarifies his position on a first course in programming at the university level (see also [[Programming for non-programmers]]): >the purpose of my proposed first course in programming [...] is not to teach people how to program a specific computer, nor is it to teach some new languages. The purpose of a course in programming is to teach people how to construct and analyze processes. Elias disagrees. He desires tools and technologies which will make our interaction and use of them "frictionless", intuitive, natural, and effortless, and therefore, programming will become unnecessary: >I have a feeling that if over the next ten years we train a third of our undergraduates at M.I.T. in programming, this will generate enough worthwhile languages for us to be able to stop, and that succeeding undergraduates will face the console with such a natural keyboard and such a natural language that there will be very little left, if anything, to the teaching of programming… Mateas (the author of the article) comments on this: >The problem with this vision is that programming is really about describing processes, describing complex flows of cause and effect, and given that it takes work to describe processes, programming will always involve work, never achieving this frictionless ideal. Any tools that reduce the friction for a certain class of programs, will dramatically increase the friction for other classes of programs. But, I think that Licklider hits the nail on the head: >I think the first apes who tried to talk with one another decided that learning language was a dreadful bore. They hoped that a few apes would work the thing out so the rest could avoid the bother. But some people write poetry in the language we speak. Perhaps better poetry will be written in the language of digital computers of the future than has ever been written in English. And Mateas comments on that: >What I like about this is the recognition that computer languages are expressive languages; programming is a medium. Asking that programming should become so “natural” as to require no special training is like asking that reading and writing should become so natural that they require no special training. Expressing ideas takes work; regardless of the programming language used (and the model of computation implicit in that programming language), leaning how to express oneself in code will always take work. >[...] >Perlis makes it clear that programming is a medium, in fact the medium peculiarly suited for describing processes, and as such, a fundamental component of cultural literacy, and a fundamental skill required of new media practitioners and theorists.
In a [[conversation|https://www.brainpickings.org/2016/03/07/sarah-kay-interview/]] between Maria Popova (of ~BrainPickings fame) and the poet [[Sarah Kay|http://www.kaysarahsera.com/about]], Kay told the following fable: >A girl walks up to a construction site and asks the first man she sees, “Excuse me, what are you doing?” And he says, “Oh, can’t you see I’m laying bricks?” She then walks up to the second man she sees, who is doing the exact same thing the first one was doing, and says, “Excuse me, what are you doing?” And he says, “Oh, can’t you see I’m building a wall?” And then she reaches the third man, who is doing the same thing as the previous two, and she says, “Excuse me, what are you doing?” And he says, “Oh, can’t you see I’m building a temple?” And Kay continues: >I think of that fable a lot, because it’s not so much about what kind of a man you are — it’s about how you look at the work you’re doing. And I don’t think it’s a judgment on any particular way of looking at the world — in fact, I think we all probably contain all three of those, and we shift in and out depending on where we are in our lives, or even in our day. And then Kay explains how it applies to her work and experience as a poet, and it sounds very similar to how I'd describe my experience teaching programming: >For me, when I’m creating a poem, it feels like I’m laying bricks — it’s very logistical, a physical movement of words, putting them together, focused on the minutia of the poem. And when I’m in schools, working with young people, I’m focusing on building connections with them and for them — that feels like building a wall, creating something that’s part of something else. The temple part is a much rarer moment of being able to tap into something bigger than yourself. But what’s so wonderful about all of this is that if you focus on one of the three for too long, you lose sight of the other two — so it requires a lot of shifting and balancing in order to get anything done at all. The "zooming" in and out of the various levels is very real in my experience. It usually ties into some Big Ideas (the ''Temple'') I am trying to understand, connect, demonstrate, teach. Then it drops down to the implementation (the ''Bricks''), creating programs one character, line, function, object, module at a time. And then it goes up, tying together (the ''Wall'') the implementation back to the vision, finding and filling the holes conceptually and programmatically, and communicating, demonstrating, teaching, practicing it. Kay mentions that the transitions are often fast and fluid, which is also reflected in my programming technique, which [[Brian Harvey|https://people.eecs.berkeley.edu/~bh/]] calls [[Bricolage|http://www.wisegeek.com/what-is-bricolage.htm]] ([[bricolage programming|http://shura.shu.ac.uk/12649/3/Rose%20Bricolage%20programming%20problem%20solving%20ability.pdf]]). (I find it interesting/serendipitous that the word bricolage sounds similar to brick, even though the origin (French) actually means something entirely (?) different: DIY (Do It Yourself) :) In an article titled [[""|http://www.papert.org/articles/EpistemologicalPluralism.html]]]] Papert and Turkle write: >Levi-Strauss used the idea of bricolage to contrast the analytic methodology of Western science with what he called a "science of the concrete" in primitive societies.11 The bricoleur scientist does not move abstractly and hierarchically from axiom to theorem to corollary. Bricoleurs construct theories by arranging and rearranging, by negotiating and renegotiating with a set of well-known materials. > >If we take Levi-Strauss's description of the two scientific approaches as ideal types and divest them of his efforts to localize them culturally, we can see both in how people program computers. For some people, what is exciting about computers is working within a rule-driven system that can be mastered in a top-down, divide-and-conquer way. Their structured "planner's" approach, the approach being taught in the Harvard programming course, is validated by industry and the academy. It decrees that the "right way" to solve a programming problem is to dissect it into separate parts and design a set of modular solutions that will fit the parts into an intended whole. Some programmers work this way because their teachers or employers insist that they do. But for others, it is a preferred approach; to them, it seems natural to make a plan, divide the task, use modules and subprocedures. > [...] >While hierarchy and abstraction are valued by the structured programmers' "planner's" aesthetic, bricoleur programmers, like Levi-Strauss's bricoleur scientists, prefer negotiation and rearrangement of their materials. The bricoleur resembles the painter who stands back between brushstrokes, looks at the canvas, and only after this contemplation, decides what to do next. Bricoleurs use a mastery of associations and interactions. For planners, mistakes are missteps; bricoleurs use a navigation of midcourse corrections. For planners, a program is an instrument for premeditated control; bricoleurs have goals but set out to realize them in the spirit of a collaborative venture with the machine. For planners, getting a program to work is like "saying one's piece"; for bricoleurs, it is more like a conversation than a monologue. >[...] >In describing bricoleur programmers, we have made analogies to sculptors, cooks, and painters. Bricoleurs are also like writers who don't use an outline but start with one idea, associate to another, and find a connection with a third. In the end, an essay "grown" through negotiation and association is not necessarily any less elegant or easy to read than one filled in from an outline, just as the final program produced by a bricoleur can be as elegant and organized as one written with the top-down approach. >[...] >With a structured programming style, one usually does not feel comfortable with a construct until it is thoroughly black-boxed, with both its inner workings and all traces of the perhaps messy process of its construction hidden from view. Many programmers feel a sense of power when they use black-boxed programs, perhaps because of the thought that others might take them up exactly as frozen. > >But black-boxing makes other programmers nervous rather than exultant. [...] When programming, bricoleurs tend to prefer the transparent style, planners the opaque, but the program's authorship is a critical variable in this preference. Planners want to bring their own programs to a point where they can be black-boxed and made opaque, while bricoleurs prefer to keep them transparent. But when dealing with programs made by others, the situation is reversed. Now, the bricoleurs are happy to get to know a new object by interacting with it, learning about it through its behavior the way you would learn about a person, while the planners usually find this intolerable. Their more analytic approach demands knowing how the program works with a kind of assurance that can only come from transparent understanding, from dissection and demonstration. >[...] >Do programmers "graduate" from bricolage when they develop greater expertise? [...] Our observations suggest that, with experience, bricoleurs reap the benefits of their long explorations, so that they may appear more "decisive" and like planners when they program on familiar terrain. And of course, they get better at "faking it." But the negotiating style resurfaces when they confront something challenging or are asked to try something new. Bricolage is a way to organize work. It is not a stage in a progression to a superior form. Indeed, there is a culture of adult programming virtuosos, the hacker culture, that would recognize many elements of the bricolage style as their own. And interviews with graduate students in computer science turned up highly skilled bricoleurs, most of them aware that their style was "countercultural." > >In the case of computation, the existence of the countercultural style challenges the idea of one privileged, "mature" approach to problems. >[...] >Bricolage does not exclude the use of subprocedures; it simply does not give their a priori delineation the status of a privileged method. Some ways that bricoleurs use subprocedures in a way that feels natural to them are captured in the following examples. First, a part of a program first conceived holistically can be demarcated as a subprocedure at any stage of programming. Second, subprocedures need not be "black boxes"; they too can grow by sculpting as the program grows as a whole. Finally, the bricoleur may use as subprocedures programs that happen to be "lying around," possibly even programs that were originally made for very different purposes.
In an article titled [[Procedural Literacy: Educating the New Media Practitioner|http://press.etc.cmu.edu/node/205]] by Michael Mateas, he talks about the discussion between CS Luminaries Alan Perlis, J. C. R. Licklider, and Peter Elias - see [[Programming as a medium for expressing and describing processes]].
Related to designing a programming course for non-programmers, Mateas points out:
>It is important not to view computation for new media students as a dumbed-down version of the traditional computer science courses. Teaching programming for artists and humanists shouldn’t merely be simplified computer science with lots of visually engaging examples, but rather an alternative CS curriculum. Traditional CS courses tend to emphasize programming as a kind of reified mathematics, emphasizing mathematical abstractions and formal systems. For new media students we need to emphasize that, while programming does have its abstract aspects, it also has the properties of a concrete craft practice. In a practice that feels like a combination of writing and mechanical tinkering, programmers build elaborate Rube Goldberg machines. In fact, the expressive power of computation lies precisely in the fact that, for any crazy contraption you can describe in detail, you can turn the computer into that contraption. What makes programming hard is the extreme attention to detail required to realize the contraption. A “loose idea” is not enough - it must be fully described in great detail before it will run on a computer. A New Media introduction to CS should be a difficult course, with the challenge lying not in programming conceived of as applied mathematics, but in connecting new media theory and history with the concrete craft practice of learning to read and write complex mechanical processes.
Mateas suggests that game programming may be a good context for such a programming course:
>Games can serve as an ideal object around which to organize a new media introduction to CS. Games immediately force a focus on procedurality; a game defines a procedural world responsive to player interaction. Additionally, unlike other procedurally intensive programs such as image manipulation tools or CAD systems, games force a simultaneous focus on simulation and audience reception. A game author must build a dynamic, real-time simulation world such that, as the player interacts in the world, they have the experience desired by the author. Unlike the design of other software artifacts that minimize the authorial voice, maintaining an illusion of neutrality, games foreground the procedural expression of authorial intentionality in an algorithmic potential space.
He finds the game development learning context advantageous, and identifies two "fruitful" components, game AI (Artificial Intelligence) and game physics ("physics engines":
>procedural literacy is not just the craft skill of programming, but includes knowing how to read and analyze computational artifacts. Because the procedural structure of games is the essence of the game medium (not mere “technical detail”), teaching procedural literacy through the creation of games is not intended merely as training for future game programmers, but as a process intensive training ground for anyone interested in computation as a medium.
>
>The fundamentally procedural nature of games can be seen by looking at the two sources of activity within a game: __game AI and game physics__.
>''Game AI'' is a concerned with “intelligent” behavior, that is, behavior that the player can read as being produced by an intelligence with its own desires, behavior that seems to respond to the player’s actions at a level connected to the meaning of the player’s actions. Game AI produces the part of a game’s behavior that players can best understand by “reading” the behavior as if it results from the pursuit of goals given some knowledge.
>''Game physics'' deals with the “dead” part of the game, the purely mechanical, causal processes that don’t operate at the level of intentionality and thus don’t respond to player activity at the level of meaning. A complete analysis of a game requires unpacking the procedural rules behind the AI and physics.
And Mateas concludes:
>[I]n the case of both game AI and game physics, the game’s response to player interaction is process intensive, depending on algorithmic response rather than playback of media assets. Thus reading and writing games and game-like artifacts requires procedural literacy, making games an ideal artifact around which to organize a procedural literacy curriculum.
In an [[interesting blog post|http://blog.kenperlin.com/?p=2739]], [[Ken Perlin|http://mrl.nyu.edu/~perlin/]] talks about the concept of a "programming literacy pipeline", analogous to a "(reading) literacy pipeline" - the process of moving a learner along from one level [of reading/books] to the next, from Dr. Seuss to Dostoevsky, and all points in between. About reading as a child, Perlin writes: > I already understood perfectly well, at the age of six, that what I was reading was exactly on the path to grown-up reading. I was reading the same language as the grown-ups, just in an early “learners” version. There was no sense that “Ten Apples Up on Top” was in some toy language. This was written English, fair and square — the same written language that my parents would read in the newspaper every morning — and I was learning to read it. And he comes up with the following observation and possible evolution of programming and push for computing literacy: >Until we come up with a suitable redefinition of what programming is for, until we embrace the utility of programming as a way for serious grown-up people to go about doing the serious things they want to do, without asking those people to pretend to be interested in becoming mathematicians or engineers, this sort of pipeline simply cannot be built for universal programming literacy. """ """ This reminds me of what [[Alan Kay]] used to say (and I try doing in my teaching :) : > A powerful way to teach is to find ideas and representations that allow “beginners to act as intermediates”, that is, for learners to immediately start doing the actual activity in some real form.
To paraphrase Ursula K. Le Guin: >Models are the wings both intellect and imagination fly on. :: ([[she said it about Words|Words are the wings both intellect and imagination fly on.]]) From the chapter on Prospects of Computer Modeling: >All models are wrong, but some are useful. :: -- George Box and Norman Draper >Computer simulations of idea models such as the [[Prisoner's Dilemma|Summary of the Prisoner’s Dilemma]], when done well, can be a powerful addition to experimental science and mathematical theory. Such models are sometimes the only available means of investigating complex systems when actual experiments are not feasible and when the math gets too hard, which is the case for almost all of the systems we are most interested in. The most significant contribution of idea models such as the Prisoner's Dilemma is to provide a first hand-hold on a phenomenon such as the evolution of cooperation for which we don't yet have precise scientific terminology and well-defined concepts. >The Prisoner's Dilemma models play all the roles I listed above for idea models in science (and analogous contributions could be listed from many other complex-systems modeling efforts as well): >''Show that a proposed mechanism for a phenomenon is plausible or implausible''. For example, the various Prisoner's Dilemma and related models have shown what Thomas Hobbes might not have believed: that it is indeed possible for cooperation albeit in an idealized form to come about in leaderless populations of self-interested (but adaptive) individuals. >''Explore the effects of variations on a simple model and prime one's intuitions about a complex phenomenon''. The endless list of Prisoner's Dilemma variations that people have studied has revealed much about the conditions under which cooperation can and cannot arise. You might ask, for example, what happens if, on occasion, people who want to cooperate make a mistake that accidentally signals noncooperation an unfortunate mistranslation into Russian of a U.S. president's comments, for instance? The Prisoner's Dilemma gives an arena in which the effects of miscommunications can be explored. John Holland has likened such models to flight simulators for testing one's ideas and for improving one's intuitions. >''Inspire new technologies''. Results from the Prisoner's Dilemma modeling literature namely, the conditions needed for cooperation to arise and persist have been used in proposals for improving peer-to-peer networks and preventing fraud in electronic commerce, to name but two applications. >''Lead to mathematical theories''. Several people have used the results from Prisoner's Dilemma computer simulations to formulate general mathematical theories about the conditions needed for cooperation. A recent example is work by Martin Nowak, in a paper called Five Rules for the Evolution of Cooperation. >What should we make of all this? I think the message is exactly as Box and Draper put it in the quotation I gave above: all models are wrong in some way, but some are very useful for beginning to address highly complex systems. Independent replication can uncover the hidden unrealistic assumptions and sensitivity to parameters that are part of any idealized model. And of course the replications themselves should be replicated, and so on, as is done in experimental science. Finally, modelers need above all to emphasize the limitations of their models, so that the results of such models are not misinterpreted, taken too literally, or hyped too much. I have used examples of models related to the Prisoner's Dilemma to illustrate all these points, but my previous discussion could be equally applied to nearly all other simplified models of complex systems. >I will give the last word to physicist (and ahead-of-his-time model-building proponent) [[Phillip Anderson|http://en.wikipedia.org/wiki/Philip_Warren_Anderson]]^^1^^, from his 1977 Nobel Prize acceptance speech: >>The art of model-building is the exclusion of real but irrelevant parts of the problem, and entails hazards for the builder and the reader. The builder may leave out something genuinely relevant; the reader, armed with too sophisticated an experimental probe or too accurate a computation, may take literally a schematized model whose main aim is to be a demonstration of possibility. ---- ^^1^^ An interesting [ext[article by Anderson: More is different|resources/anderson72more_is_different.pdf]] on the philosophy of science.
Yesterday was Friday, which is a "dress-down day" at Pinewood school. So on Fridays I wear jeans, and the rest of the week I wear dress pants. The Computer Lab has (for some reason) relatively low chairs, so it's tempting for students to occasionally put their feet on the chairs. A few days ago, a student did, and I asked them to put their feet down since "I wore my 'fancy pants' that day". Some students chuckled, and life went on. Yesterday, when I wore a pair of jeans, another student put their feet on a chair, and I asked them again to put their feet down. The student, in good humor (and while taking their feet off the chair), said: but you are not wearing your 'fancy pants' today. (this proves that students //do remember// what teachers say in class (selectively :) ) To which (seizing the "teaching moment"?) I answered (also in good humor :) : listen, when I wear my 'fancy pants' you should not put your feet on a chair. When I wear my jeans, you should not put your feet on a chair. Even when I wear my cargo pants, you should not put your feet on a chair. So, what is the conclusion? And one of the students piped up and said: the conclusion is that Mr. Mark has //at least// 3 pairs of pants. What can I say other than that this is a case of solid (and //pant//-astic) logic.
<<list-links "[tag[author]]">>
<<list-links "[tag[category]]">>
!!Why Quotes? I //love// quotes! To paraphrase [[Goethe|Johann Wolfgang von Goethe]] ([[that's what he said|When ideas fail, words come in very handy.]]): When insights need capturing, quotes (often) come in very handy. Even though, [[Sir Winston Churchill|Winston Churchill]] (a person who many of his qualities I very much admire) once said (and I quote) "It is a good thing for an uneducated man to read books of quotations", which may seem somewhat derogatory of quote-lovers^^1^^. ''Good'' quotes, in my mind, are like sharp scalpels: in one, usually short and concise sentence or two, they reveal what the quote-lover considers "a very true aspect of life". Or, to use a less-violent metaphor, they are like a "good" caricature, capturing or exposing a "very telling" (in the eyes of the beholder) side of life with very few lines/shapes. And to be able to recognize your own feelings/views (a piece of mind?) in someone else's mind (through their quote or caricature) is enjoyable, sometimes educational (to Sir Winston's point above), and sometimes fulfilling in a deep sense of recognition mixed with discovery. """ """ !!Quotes on this wiki can be searched in multiple ways, using either words appearing in the quotes or the tags associated with each quote. To search for a word appearing in a quote, use the "search" field on the top right. To ''list'' quotes by tags, open one of the lists below (by category, or by author), or use the "Tags" tab on the right. Using the tags, you can ''list'' quotes by: - [[Quote Categories]] (e.g., language, computer science, character) - [[Quote Authors]] (e.g., Alan Perlis, Albert Einstein) And as the popular New York celebrity chef ~Jean-Georges Vongerichten said: >The amuse-bouche is the best way … to express big ideas in small bites. Hope you enjoy these! ---- ^^1^^ but as Albert Einstein had said: [[Everybody is ignorant (or uneducated). Only on different subjects.|Everybody is ignorant. Only on different subjects.]].
David Epstein's book "Range - Why generalists triumph in a specialized world" covers multiple topics around professional skills, expertise, human ability, and more. Epstein is talking about "match quality" - a term economists use to describe the degree of fit between the work someone does and who they are -- their abilities and proclivities. He argues that in many cases and professions, and in situations/environments called "wicked" (where the rules are not clear, and narrow expertise is not necessarily an advantage), a range of skills and expertise, and the ability to draw on wide (not just deep) knowledge and skills and do "far transfers", connections, and analogies, is a distinct advantage. He also reviews the work of psychologist Angela Duckworth on grit, and disspells the hype around it (which, to her credit, Duckworth has been trying to do too, after her work got a lot of overexcited press). Here are some excerpts: * On switching career paths/interests: >No one in their right mind would argue that passion and perseverance are unimportant, or that a bad day is a cue to quit. But the idea that a change of interest, or a recalibration of focus, is an imperfection and competitive disadvantage leads to a simple, one-size-fits-all Tiger story: pick and stick, as soon as possible. >Responding to lived experience with a change of direction, like Van Gogh did habitually, like West Point graduates have been doing since the dawn of the knowledge economy, is less tidy but no less important. It involves a particular behavior that improves your chances of finding the best match, but that at first blush sounds like a terrible life strategy: short-term planning. """ """ * On pursuing different interests/paths: > don't consider the [professional/career] path fixed. People realize things about themselves halfway through medical school.” Charles Darwin, for example. >At his father's behest he planned to be a doctor, but he found medical lectures “intolerably dull,” and partway through his education he walked out of an operation at the grind of the surgical saw. “Nor did I ever attend again,” Darwin wrote, "for hardly any inducement would have been strong enough to make me do so.” >Darwin was a Bible literalist at the time, and figured he would become a clergyman. He bounced around classes, including a botany course with a professor who subsequently recommended him for an unpaid position aboard the HMS Beagle. After convincing his father (with his uncle's help) that he would not become a deadbeat if he took this one detour, Darwin began perhaps the most impactful post-college gap year in history. His father's wishes eventually “died a natural death.” Decades later, Darwin reflected on the process of self-discovery. “It seems ludicrous that I once intended to be a clergyman,” he wrote. """ """ * On Vertical (deep) thinking and Lateral (wide) thinking ** (this echoes what [[Jay Gould is writing about Hedgehogs and Foxes|On "The Hedgehog, the Fox, and the Magister’s Pox" by Stephen Jay Gould]]). > Eminent physicist and mathematician Freeman Dyson styled it this way: we need both focused frogs and visionary birds. “Birds fly high in the air and survey broad vistas of mathematics out to the far horizon,” he wrote in 2009. “They delight in concepts that unify our thinking and bring together diverse problems from different parts of the landscape. Frogs live in the mud below and see only the flowers that grow nearby. They delight in the details of particular objects, and they solve problems one at a time.” As a mathematician, Dyson labeled himself a frog, but contended, “It is stupid to claim that birds are better than frogs because they see farther, or that frogs are better than birds because they see deeper.” The world, he wrote, is both broad and deep. “We need birds and frogs working together to explore it. > Dyson's concern was that science is increasingly overflowing with frogs, trained only in a narrow specialty and unable to change as science itself does. "This is a hazardous situation", he warned, "for the young people and also for the future of science". > Fortunately, it is possible, even today, even at the cutting edge, even in the most hyper-specialized specialties, to cultivate land where both birds and frogs can thrive. ** and more on hedgehogs vs. foxes and their performance: >>Beneath complexity, hedgehogs tend to see simple, deterministic rules of cause and effect framed by their area of expertise, like repeating patterns on a chessboard. >> >>Foxes see complexity in what others mistake for simple cause and effect. They understand that most cause-and-effect relationships are probabilistic, not deterministic. >> >>There are unknowns and luck, and even when history apparently repeats, it does not do so precisely. >> >>They recognize that they are operating in the very definition of a wicked learning environment, where it can be very hard to learn, from either wins or losses. >> >>In wicked domains that lack automatic feedback, experience alone does not improve performance. Effective habits of mind are more important, and they can be developed.
I'm always on the lookout for ideas to make my CS courses more engaging and relevant, so... In a course titled [[Computing for poets|http://wheatoncollege.edu/lexomics/files/2016/07/Poet_syllabus_2016.pdf]] offered at Wheaton College they have an programming exercise which explores reading poems backwards. An associated reading assignment is an article in The New Yorker called [[Reading Poems Backwards|http://www.newyorker.com/books/page-turner/reading-poems-backward]]. In the article, the author, [[Brad Leithauser|https://www.poetryfoundation.org/poems-and-poets/poets/detail/brad-leithauser]], introduces it thusly: >It probably happens now and then, though perhaps you don’t give it much thought. You read a poem backward. >You pick up a poetry anthology, or you come upon a poem in a magazine, and your eye chances to fall upon its last lines. You read those. Then you read the poem. > >You read the poem, that is, knowing exactly where it’s headed. Sometimes this may occur with short stories (you read the last lines of the story first), but far less often. And as for novels—surely most of us carefully avoid the final page; given the time we’ll be investing, we’re reluctant to spoil the book’s surprise. > >Reading a poem backward is a distinctive experience, during which you’re typically asking not Where is this going?, but Can the poet justify the finish? In other words, Will the conclusion feel deserved? Towards the end (ha!) Leithauser brings up an interesting point linked to the poet [[Robert Frost|https://www.poetryfoundation.org/poems-and-poets/poets/detail/robert-frost]]: >There’s an irony in reading Frost backward, given how strongly he recoiled at working backward. He once noted, “I never started a poem yet whose end I knew. Writing a poem is discovering.“ He viewed the issue in characteristically ethical terms. To write a poem whose ending you were already aware of seemed to him a form of cheating. > >I’ve never been able to share Frost’s views on this. If a poet determines that a poem should begin at point A and conclude at point D, say, the mystery of how to get there—how to pass felicitously through points B and C—strikes me as an artistic task both genuine and enlivening. There are fertile mysteries of transition, no less than of termination. > >And I’d like to suppose that Frost himself would recognize that any ingress into a poem is better than being locked out entirely. His little two-liner, “The Secret,”^^1^^ suggests as much: “We dance round in a ring and suppose / But the Secret sits in the middle and knows.” Most truly good poems might be said to contain a secret: the little sacramental miracle by which you connect, intimately, with the words of a total stranger. And whether you come at the poem frontward, or backward, or inside out—whether you approach it deliberately, word by word and line by line, or you parachute into it borne on a sudden breeze from the island of Serendip—surely isn’t the important thing. What matters is whether you achieve entrance into its inner ring, and there repose companionably beside the Secret. The funny/serendipitous thing is that a day after reading about reading backwards, I ran into an article (OK, so it wasn't a poem :) by the sage ~Sci-Fi writer Ursula K. Le Guin titled [["Do-It-Yourself Cosmology"|Ursula K. Le Guin in defence of Science Fiction]], and the thing that caught my eye was the one line correspondence she "quotes", between GOD and a certain Sci-Fi writer. This one liner (OK, it was not at the end of the article, but close to the end :) actually caused me to read the whole article. It was wonderful!!! ---- ^^1^^ ''The Secret Sits'' We dance round in a ring and suppose, But the Secret sits in the middle and knows.
Some inspiring gems from the [[American Scientist|https://www.americanscientist.org/article/75-reasons-to-become-a-scientist]]: # 5: Curiosity. Jane Goodall The Jane Goodall Institute for Wildlife Research, Education, and Conservation ---- # 20: Because there were two inspiring teachers—one undergraduate and one graduate—who made it impossible to resist. Because from a young age I had found great personal pleasure—and still do—in the Aha! experience that goes along with success in creating things and solving problems, although I have never had any illusions about the great importance of my own particular insights. And because I was—and still am—curious about and fascinated by my own psychological processes. More over, as I get older, this curiosity grows more intense and less constrained by the psychological dogma of my early career. William Bevan Vice President ~MacArthur Foundation ---- # 22: Why? Why not? Indeed, how to avoid it? Science, I observed, licenses “thinkering”—thinking and tinkering. As such it is a haven for the neotenic, the quizzical, the (absent-) minded. Science endorses a compulsive union of play and work, of modeling, word-smithing, and number-crunching. Science integrates experience and experiment with the realms of art and craft, neither excluding nor precluding, but exploring as an end in itself. Sciencing is surely a natural propensity of our species. When I, with deliberation, became a scientist, the reasons centered on the spatiotemporal flexibility of academic science, coupled with the opportunity to confront complexity, and the excitement of meeting curious companions everywhere. Myrdene Anderson Associate Professor of Anthropology Purdue University ---- # 31: The reason I initially decided to become a scientist is that I couldn’t believe someone would actually pay me to spend the rest of my life being curious and expanding my mind. Once I arrived at graduate school, I soon recognized that there was an acute shortage of scientists worrying about why volcanoes tend to congregate in the South Pacific to create a tropical paradise. It’s a tough job, but some one has to do it. Marcia ~McNutt Associate Professor, Earth Sciences MIT ---- # 34: I never wanted to be a scientist; I wanted to be a mathematician for the sake of its consistency, which I found absent in every other endeavor. In the end it was quantum mechanics and the “uncertainty principle” which converted me to science. Still later, the need for defense drew me from work on pure science into the turbulent activities of unexpected novel applications. What I wanted I did not attain. What I got I do not regret. Edward Teller Senior Research Fellow Hoover Institution ---- # 41: There were innumerable influences in your past, but you remember only a few of the major ones, and you instinctively weave these into a plausible history explaining how you became what you presume you are. This interpretation of history is both logical and nonfalsifiable and so tends to establish its own validity. Chances are it's wrong. My nonconfident guess as to why science and engineering have proved fascinating to me is that circumstances meshed hobby with profession. The hobby was sailplanes, an outgrowth of a teenage addiction to creating model airplanes. The challenges of improving sailplane efficiency and sharpening skills for harvesting nature’s energy to keep the vehicles aloft connected me to topics such as aerodynamics, structures, meteorology, probability concepts, and bird flight, as well as to pioneering and competitions. Simultaneously, there was the stimulus of several mentors—scientists with excitement for all subjects, and the gifts of inspiring those around them to share the delight. Paul ~MacCready ~AeroVironment, Inc. ---- # 44: I loved the beauty of crystals, I loved the cleverness of gadgets, and I loved the power of understanding. If I became a scientist it meant that I would always want to go to work and would be proud of what I did. Gerald J. Wasserburg Professor of Geological Sciences California Institute of Technology ---- # 51: I went into science because as a child I had an intense curiosity, and it seemed as if science was filled with profound and deep mysteries. At an early stage, I was fascinated by numbers and their properties, and also by atoms and the particles that compose them, as well as by photons and other even-more ethereal denizens of the microworld. Later on, I became fascinated by the mysteries of language and music, and at the same time, intrigued by computers and logic; and those varied interests led to my current fascination with perception, concepts, and creativity. My early loves for math and physics have left deep tracks in my modes of thought, but I don’t think directly about them too often anymore. Douglas R. Hofstadter Professor of Human Understanding and Cognitive Science University of Michigan ---- # 59: “Why did you become a scientist?” [Long pause.] “Well... ?” “I’m thinking, I’m thinking; thirty years aren’t enough time for a satisfactory answer.” Donald Fernie Professor of Astronomy University of Toronto ----
In a short but insight-rich blog post, Mark Guzdial from Georgia Tech brings up [[a list of excellent reasons to learn Computer Science (CS)|https://computinged.wordpress.com/2017/10/18/why-should-we-teach-programming-hint-its-not-to-learn-problem-solving/]] and he adds that none of the reasons has to do with the claim that CS improves problem-solving skills. He emphasizes that there is no empirical evidence that "learning CS improves thinking", and in this he [[echos Bret Victor|http://worrydream.com/MeanwhileAtCodeOrg/]], who quotes Seymour Papert. The bulletized list is below, but it is definitely worth reading the entire blog entry with Guzdial's details and pointers. * To understand our world - (mentioning Simon Peyton Jones) we teach Chemistry or Physics but we don't necessarily expect students to become chemists or physicists. We just want them to understand chemical reactions and physical interactions in the world. We teach CS so students understand digital/computerized interactions in the world. * To study and understand processes - (quoting Alan Perlis) processes (and nowadays, more and more algorithms, which are processes too) are all around us, helping, controlling, guiding our actions and decisions. It is critical that we understand them and CS can help with that. * To be able to ask questions about the influences on our lives - (pointing to C. P. Snow) knowledge of what computing, algorithms, heuristics, machine learning, AI, and so on, can and cannot do, and how they do what they do, enables us to be critical about the computational/digital acts and their impacts/implications. * To use an important new form of literacy - (mentioning Alan Kay) knowing what's possible with computing and its power, we can be creative and express our ideas and interests using this power. * To have a new way to learn science and mathematics - (from Andrea diSessa (with Boxer), through Uri Wilensky (with NetLogo) we have new ways to examine scientific and mathematical problems through, for example, modeling, experimentation, and simulations. Computing enables another way to generate insights and solutions. * As a job skill - CS programs in school/university should not necessarily aim at feeding the high tech industry with employees, but, as Guzdial writes, learning to program gives students new skills that have value in the economy. It’s a social justice issue if we do not make this economic opportunity available to everyone. * To use computers better - this, according to Guzdial is not supported by rigorous data, but possibly points to CS knowledge and skills enabling more effective and efficient use of computing technologies. * As a medium in which to learn problem-solving - learning CS and programming per-se doesn't necessarily improve problem-solving skills, but CS and programming can be an excellent //context// to teach and practice problem solving.
From [[a paper by Alison Gopnik|resources/Gopnik Wellman - Bayes nets and causation.pdf]] (another [[interesting paper on causality|Causality - Alison Gopnik]] by Gopnik) On playing as learning (and "fishing expeditions"): >It turns out that by intervening yourself, you can rapidly get the right evidence to eliminate many possible hypotheses, and to narrow your search through the remaining hypotheses. A less obvious, but even more intriguing, result is that these interventions need not be the systematic, carefully controlled experiments of science. The formal work shows that even less controlled interventions on the world can be extremely informative about causal structure. Multiple simultaneous interventions can be as effective as intervening on just one variable at a time. Soft interventions, where the experimenter simply alters the value of a variable can be as effective as more controlled interventions, where the experimenter completely fixes that value. What we scientists disparagingly call a fishing expedition can still tell us a great deal about causal structure you don't necessarily need the full apparatus of a randomized controlled trial. >If children's playful explorations are so unconstrained how could they actually lead to rational causal learning? Recent research by Schulz (Bonawitz et al. 2011; Cook et al. 2011; Schulz et al., 2007, 2008; see also Legare, 2012) has begun to address this issue. Schulz and her colleagues have shown that children's exploratory play involves a kind of intuitive experimentation. Children's play is not as structured as the ideal experiments of institutional science. Nevertheless, play is sufficiently systematic so that, like scientific fishing expeditions, it can help children discover causal structure. This research also shows that children don't just draw the correct conclusions from the evidence they are given they actively seek out such evidence. On Hierarchical Bayesian models: >Constructivists insist that the dynamic interplay between structure and data can yield both specific kinds of learning and more profound development as well. Hierarchical Bayesian models provide a more detailed computational account of how this can happen. On the hierarchical Bayesian picture local causal learning can, and will, lead to broader, progressive, theory revision and conceptual change. On new hypotheses (innovation), language shaping thinking, and analogies: >Even hierarchical Bayes nets are still primarily concerned with testing hypotheses against evidence, and searching through a space of hypotheses. It is still not clear exactly how children generate what appear to be radically new hypotheses from the data. >Some learning mechanisms have been proposed in cognitive development to tackle this issue, including the use of language and analogy. In particular, Carey (2009) has compellingly argued that specific linguistic structures and analogies play an important role in conceptual changes in number understanding, through a process she calls Quinean bootstrapping . There is empirical evidence that the acquisition of particular linguistic structures can indeed reshape conceptual understanding in several other domains, closer to intuitive theories (see e.g. Casasola, 2005; Gopnik, Choi & Baumberger, 1996; Gopnik & Meltzoff, 1997; Pyers & Senghas 2009; Shusterman & Spelke, 2005). On difficulties with analogy-based learning, and Hierarchical Bayesian Models: >But it is difficult to see how language or analogy alone could lead to these transformations. In order to recognize that a linguistic structure encodes some new, relevant conceptual insight it seems that you must already have the conceptual resources that the structure is supposed to induce. Similarly, philosophers have long pointed out that the problem with analogical reasoning is the proliferation of possible analogies. Because an essentially infinite number of analogies are possible in any one case, how do you pick analogies that reshape your conceptual understanding in relevant ways and not get lost among those that will simply be dead ends or worse? In the case of mathematical knowledge, these problems may be more tractable because such knowledge is intrinsically deductive. But in the case of inductively inferring theories there are a very wide range of possible answers. When many linguistic structures could encode the right hypothesis, or many analogies could be relevant, the problem becomes exponentially difficult. These proposals thus suffer from the same constructivist problem we have been addressing all along. And so, again, characterizing the influence of language and analogy in more precise computational terms might be very helpful. If probabilistic and hierarchical Bayesian models can help solve the riddle of induction, then perhaps they can shed light on these other learning processes as well. On explanations helping learning, and lack of computational models: >there is a great deal of work suggesting that explanations play an important role in children's learning (Wellman 2011). Even very young children ask for and provide explanations themselves and respond to requests for explanations from others (e.g., Callanan & Oakes 1992), and these explanations actually seem to help children learn (Amsterlaw & Wellman 2006; Siegler 1995; Legare 2012). But there is no account of explanation in computational terms.
In his wonderful book //Metamagical Themas// (written in 1985, pg. 415) [[Douglas Hofstadter]] writes: A //New Yorker// cartoon from a few years back illustrates the concept perfectly. It shows a fifty-ish man holding a photograph of himself, roughly ten years earlier. In that photograph, he is likewise holding a photograph of himself, ten years earlier than //that//. And on it goes, until eventually it "bottoms out" - quite literally- in a photograph of a bouncy baby boy in his birthday suit (bottom in the air). This idea of recursive photos catching you as you grow up is quite appealing. I wish my parents had thought of it! Contrast it with the more famous Morton Salt infinite regress, in which the Morton Salt girl holds a box of Morton Salt with her picture on it - but as the girl in the picture is no younger, there is no bottom line and the regress is endless, at least theoretically.
According to Socrates, the answer to the old question of "how do we know what we don't know" is that we actually rediscover or remember what we already know, but forgot. Meno by Plato^^1^^, is [[a dialog|resources/Plato_the_Meno.pdf]] between Socrates <claimed to be roughly 67 at the time> and Meno, a young aristocrat from Thessaly. In the Meno dialog, Socrates uses one of Meno's slaves to demonstrate his idea of [[anamnesis|https://en.wikipedia.org/wiki/Anamnesis_%28philosophy%29]], that certain knowledge is innate and "recollected" by the soul through proper inquiry (see [[Kahlil Gibran's take on it|No man can reveal to you aught but that which already lies half asleep in the dawning of your knowledge.]]). I don't think that the "soulful" explanation above really explains anything. I think that this rediscovery or recollection is actually the "creation on the spot" of new knowledge, as a result of deep, thoughtful probing and questioning. I suspect that this creation of new knowledge in place (in realtime) //feels// like rediscovering something we already had (which brings up the question of [[are we discovering things or inventing them?|Is Math a human invention or a series of discoveries of truths in the real world?]]). Come to think of it (ha!), it still sounds like Ex nihilo (i.e., out of nothing), so the mysteries of the mind and the sources of knowledge are still a puzzle... On the other hand, I don't think that learning is just about rediscovering (or remembering). I believe that there is truth in what [[Eugene Ionesco|http://en.wikipedia.org/wiki/Eug%C3%A8ne_Ionesco]] said: It is not the answer that enlightens, but the [[question|David Whyte - questions]]. Sometimes we (and some AI programs, too) play with combinations of concepts and ideas, and form [[questions that lead to new explorations|John O’Donohue - questions]] and hopefully new knowledge (which in turn leads to additional concepts and ideas we can play with and combine - a spiral journey of discovery). Albert Einstein seems to refer to this spiraling questioning and discovery, too: >"Most teachers waste their time by asking questions that are intended to discover what a pupil does not know, whereas the true art of questioning is to discover what the pupil does [really] know or is capable of knowing." Sam Harris has [[a different take on rediscovery and "know thyself"|pg. 120 - SAM HARRIS: The Upload Has Begun]]. ---- 1 - [[Meno by Plato (Wikipedia)|https://en.wikipedia.org/wiki/Meno]]
In an article titled [[Relate-Create-Donate: A teaching/learning philosophy for the cyber-generation|http://hcil2.cs.umd.edu/trs/97-17/97-17.html]]^^1^^ Ben Shneiderman gives some sound advice for a productive, challenging, and effective Computer Science course, based on his experience doing and teaching CS. Shneiderman proposes: >a three-component philosophy called ~Relate-Create-Donate which stresses: > >1) Relate: work in collaborative teams > >2) Create: develop ambitious projects > >3) Donate: produce results that are meaningful to someone outside the classroom. > >''The Relate component'' emphasizes team efforts to develop communication, planning, management and social skills. The modern workplace demands proficiency in these skills, yet students are often taught to work on their own. Research on collaborative learning indicates that in the process of collaboration students are forced to clarify and verbalize their problems, thereby facilitating problem solution and anchoring/assimilating/accommodating novel information in the student's ideational structure (Ausubel, 1968). Collaboration has dangers, but when managed well, it generates intense motivation from many students, encourages learning from peers, and reduces drop out rates. > >''The Create component'' points to a fusion between learning and creative work. In creating substantial and appropriate individual and team projects, students will learn many things that serve the goals of education. Similarly, learning is useless if it does not prepare a student to be creative. Successful students create to learn, and learn to create. > >''The Donate component'' stresses the benefits of having authentic, service-oriented projects that will be meaningful and useful to someone outside the classroom. Having an outside "customer" generates intense motivation, helps clarify goals, and provides training for future professional work. Outside customers might be employers for student's who have part-time jobs, managers at volunteer organizations or campus groups, curators at local museums, or administrators at nearby schools. If possible, I would give a grade based on the amount of societal benefit produced during the semester. ---- ^^1^^ - [[local copy|resources/Shneiderman_Relate-Create-Donate_teaching_learning.pdf]]
Through no fault of our own, and by dint of now cosmic plan or conscious purpose, we have become, by the grace of a glorious evolutionary accident called intelligence, the stewards of life's continuity on earth. We have not asked for that role, but we cannot abjure it. We may not be suited to it, but here we are.
It is commonly observed that "you can take an egg and scramble it, but you'll never be able to take the (a) mess and create an egg out of it", and this is a simple and clear example of the nature of the universe (or the 'inevitable' march downhill from here...). To this, I have seen a response, which is also simple and clear: There definitely exists a process for taking the mess and "unscrambling" it, resulting in an egg. It's called a chicken. Or as the old riddle goes: Question: How do you unscramble an egg? Answer: Feed it to a chicken.
I recently cam a cross a thoughtful article by Jay ~McTighe and Grant Wiggins titled [[From Common Core Standards to Curriculum: Five Big Ideas|http://grantwiggins.files.wordpress.com/2012/09/mctighe_wiggins_final_common_core_standards.pdf]], and was pleased to see that they (like myself ;-) take it as a serious and refreshing change in the state of affairs. Id like to summarize their Big Ideas and add some comments: !!!! Big Idea #1 - The Common Core Standards have new emphases and require a careful reading. That is, this time it's not "old ideas in new packaging", but rather an opportunity to "raise the bar" on what math teaching can accomplish for learners. Also, the authors urge schools and teachers to read ALL parts of the standards, and not dive into their grade-specific sections right away. The introductory sections of the standards (starting [[here|http://www.corestandards.org/Math]]) provide very important information about vision, goals, changes in emphasis, etc., while the [[Standards for Mathematical Practice|http://www.corestandards.org/math/practice]] provide badly needed requirements for higher level cognitive and meta-cognitive skills, performance, and outcomes. !!!! Big Idea #2 - Standards are not curriculum. In short, the standards are the //what// - focusing on the outcomes and accomplishments/achievements, while the curriculum is the //how// - focusing on sequences, methods, procedures, connections, etc. Educators must map (translate) the standards to effective and engaging curricula. This is an exciting opportunity (and a big creative challenge) for educators in classrooms, at home, and in online contexts and platforms to innovate, and also implement known and effective learning techniques. Doing a thoughtful and thorough job on Big Idea #1 will "insure clarity about the end results and an understanding of how the pieces fit together.", which will lead to meaningful, engaging, and effective curricula. !!!! Big Idea #3 - Standards need to be “unpacked.” The authors suggest unpacking and analyzing the standards keeping 4 categories or "lenses" in mind: * Long term Transfer Goals ** These are the long-term skills, mindsets, habits, and practice for life (hence //transfer//) * Overarching Understandings ** These are the common themes, concepts, connections, and approaches that are effective and efficient when "thinking with math" about the world. * Overarching Essential Questions ** These are the different "lenses" that keep learners goal-oriented, focused, and critical along the processes of understanding, practicing, and solving problems. * A set of recurring Cornerstone Tasks ** These are the important performances or procedures that are part of the desired 21^^st^^ Century skills !!!! Big Idea #4 - A coherent curriculum is mapped backwards from desired performances. The curricula should not aspire to have "full coverage" of the topics mentioned in the CCSS, but rather start with the performance and desired outcomes of the learners, and map those to the topics, their sequencing, and instruction techniques. This will also reduce the risk of sequencing the curricula topics in the order they appear in the Standards (a mistake). It will also enable making meaningful and deep connections between topics, in support of achieving the desired outcomes. !!!! Big Idea #5 - The Standards come to life through the assessments. Again, like in Big Idea #1, the Standards are the //what//, and they should provide both the outcome and its "degree" or "level" or quality, as well. And that's the link to assessment, which should verify both qualitatively and quantitatively to what degree the learners have accomplished the desired goals/performances/outcomes. Here too, assessments should not aspire to have a 1-to-1 coverage of the Standards and requirements. The authors of the Standards explicitly cautioned against it by saying: “While the Standards delineate specific expectations in reading, writing, speaking, listening, and language, each standard need not be a separate focus for instruction and assessment. Often, several standards can be addressed by a single rich task.” This obviously is also relevant to Math, and may serve as a motivation to design the curricula in larger (possibly project-based) chunks, linking multiple topics, concepts, and skills together, to form more meaningful (real life) contexts and experiences, preparing learners for these kinds of more meaningful assessments.
Richard Phillips Feynman was an American theoretical physicist known for his work in the path integral formulation of quantum mechanics, the theory of quantum electrodynamics, and the physics of the ... Born: May 11, 1918, Far Rockaway Died: February 15, 1988, Los Angeles [img[Feynman Ambigram|resources/feynman_ambigram.gif][resources/feynman_ambigram.gif]] [1] ---- 1- Ambigram from [[01101001|http://www.01101001.com/ambigrams/index.html]]. See [[other ambigrams|Ambigrams by Scott Kim]] by Scott Kim
!!!On the simplicity
From [[Richard Feynman's Nobel Prize Lecture|http://www.feynmanlectures.info/other/Feynmans_Nobel_Lecture.pdf]] (1965):
> It always seems odd to me that the fundamental laws of physics, when discovered, can appear in so many different forms that are not apparently identical at first, but, with a little mathematical fiddling you can show the relationship. [...] I don’t know why this is -- it remains a mystery, but it was something I learned from experience. There is always another way to say the same thing that doesn’t look at all like the way you said it before. I don’t know what the reason for this is. I think it is somehow a representation of the simplicity of nature. [...] I don’t know what it means, that nature chooses these curious forms, but maybe that is a way of defining simplicity. Perhaps a thing is simple if you can describe it fully in several different ways without immediately knowing that you are describing the same thing.
[[This reminds me of something I heard my father saying about mathematics|On multifaceted understanding]].
!!!On the beauty
From [[The Character of Physical Law|http://people.virginia.edu/~ecd3m/1110/Fall2014/The_Character_of_Physical_Law.pdf]] (MIT Press, Cambridge, MA, 1967)
>To those who do not know mathematics it is difficult to get across a real feeling as to the beauty, the deepest beauty, of nature … If you want to learn about nature, to appreciate nature, it is necessary to understand the language that she speaks in.
>The imagination of nature is far, far greater than the imagination of man.
From [[The Feynman Lectures on Physics, 1|http://www.feynmanlectures.caltech.edu/I_toc.html]]
>Poets say science takes away from the beauty of the stars -- mere globs of gas atoms. Nothing is “mere”. I too can see the stars on a desert night, and feel them. But do I see less or more? The vastness of the heavens stretches my imagination -- stuck on this carousel my little eye can catch one-million-year-old light. A vast pattern -- of which I am a part -- perhaps my stuff was belched from some forgotten star, as one is belching there. Or see them with the greater eye of Palomar, rushing all apart from some common starting point when they were perhaps all together. What is the pattern, or the meaning, or the why? It does not do harm to the mystery to know a little about it. For far more marvelous is the truth than any artists of the past imagined! Why do the poets of the present not speak of it? What men are poets who can speak of Jupiter if he were like a man, but if he is an immense spinning sphere of methane and ammonia must be silent?
Feynman also famously recounted in a filmed interview:
>I have a friend who's an artist and he's some times taken a view which I don't agree with very well. He'll hold up a flower and say, "look how beautiful it is," and I'll agree, I think. And he says, "you see, I as an artist can see how beautiful this is, but you as a scientist, oh, take this all apart and it becomes a dull thing." And I think he's kind of nutty. First of all, the beauty that he sees is available to other people and to me, too, I believe, although I might not be quite as refined aesthetically as he is. But I can appreciate the beauty of a flower. At the same time, I see much more about the flower than he sees. I could imagine the cells in there, the complicated actions inside which also have a beauty. I mean, it's not just beauty at this dimension of one centimeter: there is also beauty at a smaller dimension, the inner structure...also the processes. The fact that the colors in the flower are evolved in order to attract insects to pollinate it is interesting -- it means that insects can see the color. It adds a question -- does this aesthetic sense also exist in the lower forms that are...why is it aesthetic, all kinds of interesting questions which a science knowledge only adds to the excitement and mystery and the awe of a flower. It only adds. I don't understand how it subtracts.”
This view is echoed by the following:
In a poetry reading which was part of a yearly event called The Universe in Verse, [[the NASA astrophysicist Natalie Batalha read a poem by Edna St. Vincent Millay|https://www.brainpickings.org/2018/08/03/the-universe-in-verse-natalie-batalha-edna-st-vincent-millay/]] ("Renascence"), but prefaced it with a personal experience she had, while doing planetary research using the powerful telescopes in the desert in Chile. Her account ([[video clip, starting at ~4:10 min|https://vimeo.com/282887910]]) beautifully expresses the point of how science and knowledge can make an experience even more intense, deep, and beautiful.
>The sky in the Southern Hemisphere is magnificent. The Milky Way arches straight overhead and it's very crisp; you've got the Large and Small Magellanic clouds which are satellites of our own galaxy; you have Alpha Centauri which is the nearest start to our Solar System; the planets were arcing overhead along the ecliptic, and a gibbous Moon was out.
>I climbed up to the rooftop [of the building next to the telescope structure], and I laid down on top of the roof, and just took it all in. And for the first time, the dome of the sky over me transformed from a flat surface to a three dimensional landscape. It was because of my deep knowledge of astronomy, that I could visualize well all the relative positions of these objects. And so I was no longer a mere human stuck in a gravity well under a bell jar, I became the Earth itself traveling through the space. I was literally the Universe. And my knowledge made all of this experience so intensely beautiful.
[[Richard Hamming|http://en.wikipedia.org/wiki/Richard_Hamming]]: American mathematician whose work had many implications for computer science and telecommunications. Born: February 11, 1915, Chicago Died: January 7, 1998, Monterey Books: Coding and Information Theory, and more
Type the text for 'Robert Frost'
(July 30, 1920 – January 12, 1998) was an American business executive and author who is noted for transforming Avis into a rental car giant. Known for his book //Up the Organization//.
This is a step-by-step worked out example of the implementation of the [[RSA algorithm|http://en.wikipedia.org/wiki/RSA_%28algorithm%29]], as originally described by Ron Rivest, Adi Shamir and Leonard Adleman (hence, R S A). You can follow this simplified example along, using the [[NetLogo implementation/simulation|math/netlogo/RSAcrypto.html]] (Imagine if you will) a spy agency (henceforth The Agency) wanting to exchange information (secret messages) with a group of spies out in the field. * The Agency selects 2 prime numbers, say 17 and 19. * It calculates __the product N__ (17 x 19 = 323), and the public key range ( (17 - 1) x (19 - 1) = 16 x 18 = 288 ). This number, N, will be used later. * Then, The Agency selects another prime within the public key range, say 11 (which is smaller than 288 and is not a factor of 288, i.e., 288 cannot be divided by 11 without a remainder). This number will be used later as the __public key__ * Finally, The Agency selects another number (say, 131), the __private key__, which when multiplied by its public key (say, 11) and divided by the public key range (in our case 288), leaves a remainder of 1 (so, (131 x 11) / 288 = 1441 / 288 = 5 and a remainder of 1). Now, the agency publishes its public key (11) and the product N (323) to its agents. If those numbers fall into enemy hands, there is no harm done. * An agent wanting to send a message to The Agency, takes the message (or data, say 32, in the [[NetLogo simulation|math/netlogo/RSAcrypto.html]]), and encrypts it by raising the data to the power of the public key, and taking the remainder after dividing by N (so, (data^^public-key^^) mod N = 32^^11^^ mod 323 = 36,028,797,018,963,968 mod 323 = 230 ). The data (32) can stand for a letter or symbol, and if the message consists of multiple letters, words, sentences, and symbols, this operation (taking to the power and then mod) is repeated for each letter/symbol. * The agent sends the message (230) to The Agency, and again, if it falls into enemy hands, there is no harm done, since this is not really the secret message (or data, namely 32). Moreover, if The Enemy intercepts both the encrypted message (230) and the public key (11) and the range (323), they still cannot figure out the secret message (32). * When The Agency receives the encrypted message (230), it uses its private key (131) to decrypt it by raising the encrypted message to the power of the private key and dividing by the product, and keeping the remainder (so, (encrypted-data^^private-key^^) mod N = 230^^131^^ mod 323 = 2.4341454095880723262526112555729e+309 mod 323 = 32). This is the original secret message sent to The Agency by the agent/spy. As you can see, the calculations of encrypting and decrypting involve pretty big numbers, and cracking the keys requires calculations and factorizations of big primes, which makes it very difficult, but __not__ impossible to crack RSA encryptions.
In an [[article in the WSJ|https://www.wsj.com/articles/rules-for-modern-living-from-the-ancient-stoics-1495723404]], Massimo Pigliucci writes about "Know what you can control, be in the moment and other tips from Marcus Aurelius, Seneca and Epictetus", and boils it down to a few key lessons/messages: * ''Learn to separate what is and isn’t in your power.'' This lets you approach everything with equanimity and tranquility of mind. ** Within our power are opinion, motivation, desire, aversion and, in a word, whatever is of our own doing; not within our power are our body, our property, reputation, office and, in a word, whatever is not of our own doing. *** In a thoughtful review of [[Seneca's view on the shortness of life|https://www.brainpickings.org/2014/09/01/seneca-on-the-shortness-of-life/]] Maria Popova of ~BrainPickings quotes him: >> You are arranging what lies in Fortune’s control, and abandoning what lies in yours. What are you looking at? To what goal are you straining? The whole future lies in uncertainty: live immediately. * ''Contemplate the broader picture.'' Looking from time to time at what the Stoics called "the view from above" will help you to put things in perspective and sometimes even let you laugh away troubles that are not worth worrying about. * ''Think in advance about challenges you may face during the day.'' A prepared mind may make all the difference between success and disaster. * ''Be mindful of the here and now.'' The past is no longer under your control: Let it go. The future will come eventually, but the best way to prepare for it is to act where and when you are most effective—right here, right now. * ''Before going to bed, write in a personal philosophical diary.'' This exercise will help you to learn from your experiences—and forgive yourself for your mistakes.
https://en.wikiquote.org/wiki/Sallustius : Sallustius or Sallust (Σαλούστιος) was a 4th-century Latin writer, a friend of the Roman Emperor Julian. He wrote the treatise On the Gods and the Cosmos, which owes much to the work of Iamblichus of Chalcis, who synthesized Platonism with Pythagoreanism and theurgy, as well as to Julian's own philosophical writings.
""" SATAN, n. One of the Creator's lamentable mistakes, repented in sashcloth and axes. Being instated as an archangel, Satan made himself multifariously objectionable and was finally expelled from Heaven. Halfway in his descent he paused, bent his head in thought a moment and at last went back. "There is one favor that I should like to ask," said he. "Name it." "Man, I understand, is about to be created. He will need laws." "What, wretch! you his appointed adversary, charged from the dawn of eternity with hatred of his soul—you ask for the right to make his laws?" "Pardon; what I have to ask is that he be permitted to make them himself." It was so ordered. """ :-- Ambrose Bierce, The Unabridged Devil's Dictionary
Science does not foreclose^^1^^ possibility, including discoveries that overturn fundamental assumptions, and that it is not a final statement about reality but a highly fruitful mode of inquiry into it. -- Robinson, in her book //Absence of Mind// ---- ^^1^^ foreclose = close, settle, or answer beforehand.
""" She's been in this world for over a year, and in this world not everything's been examined and taken in hand. The subject of today's investigation is things that don't move by themselves. They need to be helped along, shoved, shifted, taken from their place and relocated. They don't all want to go, e.g. the bookshelf, the cupboard, the unyielding walls, the table. But the tablecloth on the stubborn table —when well-seized by its hems— manifests a willingness to travel. And the glasses, plates, creamer spoons, bowl are fairly shaking with desire. It's fascinating, what form of motion will they take, once they're trembling on the brink: will they roam across the ceiling? fly around the lamp? hop onto the windowsill and from there to a tree? Mr. Newton still has no say in this. Let him look down from the heavens and wave his hands. This experiment must be completed. And it will. """ (translated, from the Polish, by Stanislaw Baranczak and Clare Cavanagh)
There is a common misconception that following your passion will inevitably lead you to great success. Ask any high-achieving person in their field — from sport to business—how they got to where they are, and it's likely they will cite “passion” as at least one of the reasons. However, this familiar story obscures the truth, which is that you can feel incredibly passionate about a project or idea, and it can still fail—most likely causing your enthusiasm for that project to wane, too. ''Success tends to induce passion, but passion does not necessarily equal success.'' In his book "How to Fail at Almost Everything and Still Win Big: Kind of the Story of My Life", Scott Adams writes: >It's easy to be passionate about things that are working out, and that distorts our impression of the importance of passion. > >My hypothesis is that passionate people are more likely to take big risks in the pursuit of unlikely goals, and so you would expect to see more failures and more huge successes among the passionate. Passionate people who fail don't get a chance to offer their advice to the rest of us. But successful passionate people are writing books and answering interview questions about their secrets for success every day. Naturally those successful people want you to believe that success is a product of their awesomeness, but they also want to retain some humility. You can't be humble and say, “I succeeded because I am far smarter than the average person.” But you can say your passion was a key to your success, because everyone can be passionate about something or other. Passion sounds more accessible. If you're dumb, there's not much you can do about it, but passion is something we think anyone can generate in the right circumstances. Passion feels very democratic. It is the people's talent, available to all. It's also mainly bull*. In other words, we are listening to (or accepting as truth) the successful (and passionate) survivors, which reminds me of the allegory Richard Hamming is describing (referring to Eddigton): >"Some men went fishing in the sea with a net, and upon examining what they caught they concluded that there was a minimum size to the fish in the sea."
!!!The Mind of a Master Brain Teaser By ALEXANDRA ALTER for The Wall Street Journal Scott Kim has been called `the M.C. Escher of the alphabet' for [[his ambigrams|Ambigrams by Scott Kim]]^^1^^ words and phrases that can be read in multiple directions. Scott Kim has an odd talent he's a brilliant problem maker. Mr. Kim belongs to an elite cadre of "puzzle masters" who spend their days building logical mazes and brain teasers. In more than 20 years as a professional puzzle designer, Mr. Kim has worked on everything from word, number and logic puzzles to toys such as Railroad Rush Hour and computer games such as "Obsidian" and "Escher Interactive," which features interactive puzzles based on M.C. Escher's optical illusions. Lately, he has been developing smartphone game apps and contributing a bimonthly puzzle column to Psychology Today. Mr. Kim defines puzzles as "problems that are fun to solve and have a right answer," as opposed to everyday problems like traffic, which, he noted, "are not very well-designed puzzles." "My goal as a puzzle designer is to create a meaningful experience for the player, not just 'I solved it,' " he said. Mr. Kim, who is youthful looking at 55, with a round, unlined face and sheepish smile, has mostly shunned popular forms like Sudoku or crosswords, which he dismissed as "filling out someone else's matrix." Instead, he aims to invent new forms, specializing in computer and print puzzles that pose logical problems or test mathematical or visual skills. He often begins by choosing a cognitive area or skill he wants the puzzle to test. One puzzle challenged players' ability to visualize negative space, the white space that surrounds and defines shapes and letters. A smartphone game he's designing requires players to think three-dimensionally by reassembling, in the fewest possible steps, a car or building that has been cut into pieces. !!!Three Puzzles From "The Playful Brain," by Richard Restak and Scott Kim: Find a sequence of four letters that appear in two different five-letter words, differing by one letter. The words end in "P" or "H"; the first four letters are the same. Hint: the first letter is "C," and the words mean "hold hands or fight." Arrange numbers 0 to 9 so that three numbers plus three other numbers equal the four remaining numbers. (Start by drawing 10 boxes to hold three digits in the top row, three in the middle row and four in the bottom row, which will be the sum of the top two rows). Four people sit down for dinner in four different chairs and want to sit in a different combination each night. How many nights can they sit down without repeating an arrangement? Andrea Bartz, news editor for Psychology Today, said his puzzles are always harder than they look. "They're deceptively and elegantly simple," Ms. Bartz said. "It looks like it should be very easy, but it takes a long time." Growing up in Los Angeles, Mr. Kim was obsessed with magic and mathematics. He began drawing mazes and creating crossword puzzles in the second grade. In the sixth grade, he made his first original puzzle. He began folding letters of the alphabet made out of construction paper to make other letters. He folded the letter F over so that the base covered the shorter horizontal line and formed a U shape. "This excited me to no end," said Mr. Kim, who still uses the puzzle in lectures, asking people to guess the letter underneath. (Most guess L.) Mr. Kim studied music during college and received a self-designed Ph.D. in computers and graphic design at Stanford. As a college student, he wrote letters to Martin Gardner, the author and mathematical-games columnist for Scientific American. The two began corresponding, and Mr. Kim sent him a new take on a classic logic puzzle. Scientific American published the puzzle, and Mr. Kim realized he could make a living from something most people view as a form of procrastination. Mr. Kim works on puzzles daily from his home in Burlingame, Calif., a Bay Area suburb with "an excessive number of trees," Mr. Kim said. He lives with his wife and two kids, ages 12 and 4, in a house teeming with art supplies, board games, mathematical toys, art books and instruments, including piano and drums. He likes changing locations frequently throughout the day, moving from his office to the kitchen table, then to the library or a coffee shop. Each time he changes surroundings, he tackles the problem anew. "I often find that the amount of progress I make is proportional to the number of times I start," he said. He's constantly doodling and carries a 3-by-5-inch notebook to record ideas, notes and images. He borrows ideas for puzzles from architecture, music, science and art (favorite designers include Milton Glaser and Charles and Ray Eames). Occasionally, he gets ideas from dreams. After he dreamed he was surfing on waves of color, Mr. Kim had an idea for a computer game whose goal is to stay on the red wave. He takes frequent walks because he feels that increased blood flow keeps his brain alert and prefers strolling rather than sitting when he meets with other game designers or book or magazine editors. "If you're sitting across the table from someone, the geometry of the situation says confrontation," he said. "If you're walking with somebody, you're heading in the same direction, and the spatial dance you're doing is a little more cooperative." Designing puzzles can be exhausting. To unwind, and spark ideas, Mr. Kim dabbles in music and art. He composes Bach-like fugues, often in his sleep, and has studied the dizzying art of M.C. Escher. Science-fiction writer Isaac Asimov called him "the Escher of the alphabet" for his ambigrams words and phrases that can be read in multiple directions. (An example: Write the word "chump" in cursive but leave the semicircle of the "p" open so it doesn't touch the p's tail. Flip it upside down.) He defines a good puzzle as one that gets people to look at the problem in a new or counterintuitive way. "What I always want is to have several little 'aha' moments where your brain is very happy," he said. ---- ^^1^^ - [[01101001|http://www.01101001.com/ambigrams/index.html]] has a nice collection of ambigrams
While teaching a course at Citizen Schools in Campbell, CA., this semester, I experienced what I'd call a "seagull moment". I was teaching middle school students a STEM (Science, Technology, Engineering, Math) [[course called Amazing Mazes|The "Amazing Mazes" course]], which I had developed a year ago (including both many [[student interactive activities|http://employees.org/~hmark/courses/amazingmazes/index.html]], and a set of [[resources and lesson plans|It's all in the game - learning programming and math]] for future teachers). One of the important concepts in learning in general, and in [[Computational Literacy|A Framework for Computational Thinking, Computational Literacy]] in particular, is ''levels of abstraction''^^1^^. The idea that different mental models (and levels of abstraction) are essential to understanding and learning, and that they can serve different purposes is key to human growth and performance. The Amazing Mazes course is using computers to build mazes in a 2D plane (on the computer screen), creating "maze walkers" (think, "mice"), and teaching them, through programming, to successfully navigate through these mazes (or "find the cheese", so to speak). In one of the lessons the students build a maze by drawing lines, specifying the coordinates of the starting point and ending point of each line. As they enter the coordinates for the maze, they see the lines on the screen (immediate feedback), but also a running list of "draw-line" commands with the entered coordinates as command parameters. The list of commands is displayed in a "history box" (text area on the screen), so that the students see side-by-side two very different representations of their maze: one is the actual shape of the maze, made of the lines they have drawn on the screen, and the other, a list of commands and parameters. And the question is: which of these forms "is really the maze"? To emphasize the strong relationship between the visual and programmed version of the maze, the user interface enables the students to copy and paste the list of commands from the "history box" into a "command-input" area, then run/execute the commands, and see their maze drawn for them. This connects in a powerful way math and programming, different forms and models. It is hard to fully grasp these concepts in middle school. When introducing these ides in the course, I felt a bit like Fletcher Lynd Seagull in Richard Bach's wonderful story [[Jonathan Livingston Seagull|resources/Bach-Jonathan-Livingston-Seagull.html]]. Fletcher Gull had been mentored by Jonathan Gull for a while, and when it's time for Jonathan to move on (to another plane (of existence)? To another level of abstraction? ;-) , Fletcher is left in charge of a group of young seagulls who are very eager to learn how to fly as superbly as Jonathan and Fletcher. Fletcher, still saddened by his friend and mentor leaving, tries to convey to his young students some of the wisdom he acquired (with a lot of effort/practice) from Jonathan, and starts his first lesson with the group: >...Fletcher Gull dragged himself into the sky and faced a brand-new group of students, eager for their first lesson. "To begin with" he said heavily, "you've got to understand that a seagull is an unlimited idea of freedom, an image of the Great Gull, and your whole body, from wingtip to wingtip, is nothing more than your thought itself." >The young gulls looked at him quizzically. Hey, man, they thought, this doesn't sound like a rule for a loop. >Fletcher sighed and started over. "Hm. Ah... very well," he said, and eyed them critically. "Let's begin with Level Flight." As it turns out, one 7th grade girl in class got an important piece of the connection and usefulness of the two forms of representing a maze. Instead of just copying and pasting the commands and parameters from the history box into the command input, and running them (to display the original maze), she added 10 (I guess she correctly reasoned that it'd be easier) to each command parameter (coordinate in the x-y plane), and then ran the commands. I don't know who was more pleased with the resulting translated (shifted) shape on the screen, I, because I was able to teach, or she, because she was able to learn! ---- ^^1^^ [[Bret Victor|http://worrydream.com/]] gives an excellent and beautifully done [[example of going up and down the abstraction ladder|http://worrydream.com/LadderOfAbstraction/]]
!!! In his book called //5000 B.C. and Other Philosophical Fantasies// Raymond Smullyan's lists "self-annihilating" sentences: (for a more complete (ha! or shall we say more perfect? :) list see [[Self-Annihilating Sentences: Saul Gorn's Compendium of Rarely Used Clichés|https://repository.upenn.edu/cgi/viewcontent.cgi?article=1522&context=cis_reports]] , also on [[GD|https://drive.google.com/open?id=1_OnfzkVKdCkHN64E7zJwG6NYrL88myX6]]) * Before I begin speaking, there is something I would like to say. * I am a firm believer in optimism because without optimism, what else is there? * Half the lies they tell about me are true. * Every Tom, Dick, and Harry is called John. * Having lost sight of our goal, we must redouble our efforts! * I'll see to it that your project deserves to be funded. * I've given you an unlimited budget, and you have already exceeded it! * A preposition must never be used to end a sentence with. * This species has always been extinct. * Authorized parking forbidden! * If you're not prejudiced, you just don't understand! * Inflation is an economic device whereby each person earns more than the next. * Superstition brings bad luck. * That's a real step forward into the unknown. * You've outdone yourself as usual. * Every once in a while it never stops raining. * Monism is the theory that anything less than everything is nothing. * A formalist is one who cannot understand a theory unless it is meaningless. !! And a few others ( from [[a blog on the princeton.edu site|http://www.cs.princeton.edu/~chazelle/courses/BIB/cuttheknot.htm]]) * E.Harrison: "Is it true that philosophy has never proved that something exists?" Bertrand Russell: "Yes, and the evidence for it is purely empirical." * Hofstadter's Law: It always takes longer than you expect , even when you take into account Hofstadter's Law. * Nostalgia isn't what it used to be. * Break every rule. * All generalizations are misleading. * If somebody loves you, love them back unconditionally. * We have to believe in free-will, we have no choice. * Understatement is a zillion times more effective than exaggeration. !!!Questions that contain their own answers (a few samples:) * In 1978, Raymond Smullyan wrote a book about logical puzzles. //What is the name of this book?// * I am the square root of -1. Who am //I//? * What would the value of 190 in hexadecimal //be//? * Twenty-nine is a //prime// example of what kind of number? * The reciprocal of [[sqrt(2)|https://en.wikipedia.org/wiki/Square_root_of_2]] is half of what number? * How many consonants are in //one//? How many consonants are in //two//? How many consonants are in //three//? * What do you do to the length of an edge of a //cube// to find its volume?
In an interesting [[talk (45 min. video)|https://mediax.stanford.edu/page/john-seely-brown-mediaX2017]] given at #mediaX2017 Conference at Stanford, John Seely Brown (former Chief Scientist of Xerox Corporation and former director of the Xerox Palo Alto Research Center (PARC)) talked ([[slides|http://johnseelybrown.com/sensemaking.pdf]]) about what it means (and how the meaning changed) to make sense and learn in the new environment we are in, in the 21st century (the "post ~AlphGo world" as he calls it). !!!His main points !!!! Looking from an operational perspective * In the Push Economy of the 20th Century, 20th century infrastructure drove organization architectures where Scalable Efficiency was the holy grail. ** predictable ** hierarchy ** control ** organizational routines ** minimize variance * 21st Century infrastructure: no stability in sight S-curve driven by continual exponential advances in computation ** rapid set of punctuated jumps for the next 20-40 years * Three quite different eras required quite different learning strategies & ways of being ** Industrial Age - like a big steamship ** Early Digital Age - like a nimbler sailboat ** Digitally Networked Age - like a whitewater kayak * This new era (Digitally Networked Age) is no longer just about deepening individual expertise within a silo. ** Instead, it is also about participating in & shaping knowledge flows, where the goal is to be balanced & embedded when all is in flux * Critical skills for a white water world (besides [[reading deeply and widely|A Helpful Guide to Reading Better - Farnam Street]]) ** skillfully reading the currents and disturbances of the context, ** interpreting the flows for what they reveal of what lies beneath the surface, ** leveraging the currents, disturbances and flows for amplified action. * reading context is becoming more important, but it isn’t always simple ** Data analytics can’t do everything. ** Knowing what questions to ask is key. (since, [[questions are like lanterns|John O’Donohue - questions]]) ** ''data'' is_not_equal_to ''information'' is_not_equal_to ''beliefs'' is_not_equal_to ''values'' ** And for that imagination is crucial^^1^^ especially if we are to escape the tyranny of the present (the fixed way we currently view and think about a situation) * Given the relentless pace of change & disruptions. ** Incremental learning will no longer suffice!! [img[The Big Shift|./resources/big shift.png]] * How do you do that? ** A simple start: “How often do you get out of your comfort zone?” *** Increasingly important in a global world of constant change! *** honor & amplify serendipity ** Orchestrating Serendipity can be more than just luck!!! *** Choose Serendipity Environments *** Develop Serendipity Practices *** Enhance Serendipity Preparedness ** In all encounters: develop and practice deep listening with reciprocity [img[Serendipity|./resources/serendipity.png]] ** Also consider: ''Reverse Mentorship'' *** can be an amazing source of insight *** but can also be humbling. **** "we have so much to learn if we are ready to look stupid" *** Endless Newbie is the new default for everyone, no matter your age or experience. That should keep us humble. (from the book [[The Inevitable by Kevin Kelly|http://kk.org/books/the-inevitable/]]) !!!! Looking form an epistemological perspective (Knowing (the what) and understanding (the how and the why)) * How do we come to understand given the pace of change & dense interconnectivity? ** Incremental learning no matter, how fast we do it, will no longer suffice. ** We must be willing to regrind our conceptual lenses, often! We must be able and willing to constantly reframe. *** (Piaget) Assimilation ----> Accommodation - we need to become better at breaking the old/existing frames and create new ones (accommodating new learning) * Living in exponential times in the global networked age that is densely interconnected many of our problems are [[wicked problems|https://www.wickedproblems.com/1_wicked_problems.php]] ** They are not just complicated; they are complex ** quoting Parag Khanna, The Second World: *** When we try to pick out anything by itself, we find it hitched to everything else in the universe. There is no special sphere of the environment, no distinct lands of oil, no detached global economy, and no separate issue of public health. ** Wicked Problems: As soon as you start to solve them they morph. *** The “Catch 22” of wicked problems is that you cannot learn about the problem without trying solutions, but every solution you try has lasting unintended consequences that are likely to spawn new wicked problems. *** Examples of wicked problems include: global warming, the financial crisis, terrorism, environmental design, homeless. * We need new ways to move from mechanistic thinking to understanding contexts/problems that evolve: ** Sets of exchanges with complex feedback loops ** Dynamic attractors ** Network affordances and contextual propensities * Karl Popper, the great philosopher, said that [[all problems are either clouds or clocks|http://www.the-rathouse.com/2011/Clouds-and-Clocks.html]]. ** To understand a clock you can take it apart, its individual pieces and you study the pieces and then you can understand how a clock works. A cloud – you can’t take apart a cloud. A cloud is a dynamic system. A cloud you can only study as a whole. ** One of the problems we have as a culture is we take clouds and pretend they are clocks. * Perhaps this whitewater world may require “a new sense – a seventh sense” ([[Joshua Cooper Ramo|http://joshuacooperramo.com/]]) ** The seventh sense is the ability to look at any object and see (or imagine) the way in which it is changed by connection. Whether you are commanding an army, running a Fortune 500 company, planning a great work of art, or thinking about your child's education. ** We have a Crisis of Imagination. We need to “see” the ways that something/everything is changed by hyper-connectivity. ** Or even just plain normal connectivity where connections are not obvious and making sense is elusive * We need to use Abductive Reasoning: ** imagining possible stories that suggest how something could have come about and then testing them. ** A form of sense making when the facts don’t add up or contradict each other. ** This imagination^^1^^ is the power or capacity of humans to form internal images of objects and situations (visual, auditory or motor images). It: *** closes the gap between what is novel and what is known. *** finds connections between things that are not obvious. *** plays with boundaries. It lets partial thoughts jump fences. *** engages in sense-breaking in order to make sense in a new way – to see new possibilities. *** and in seeing new possibilities, it helps us escape the tyranny of the present (the fixed way we currently view and think about a situation). ** Within the range of abductive reasoning, there is a shift from normative sense-making to sense-breaking, where one widens the gap and then resolves it, with the imagination. ** Imagination cannot just be an add on. It is not just relevant within the domains of the ‘arts.’ It is crucial in sense-making & and even more so in sense-breaking/sense-making !!!! Looking from an ontological perspective (a new way of being) * The unique power of the human imagination^^1^^ comes in part from its ability to integrate opposing qualities, like emotion and reason, curiosity and certainty. ** we all are deeply engaged and practiced in "thinking man" and "building man", and we learn by creating and reflecting. ** but we don't take seriously the value of "playing man" and the value of play, boundary testing, alternative scenarios, etc., are and should be playing in our lives [img[Imagination as a blender|./resources/blending imagination.png]] * Cultivating a blended ontology with human/machine ** we need to blend in to this state of being and becoming, AI (Artificial Intelligence) and IA (Intelligent Augmentation) ** the imagination (as the binding agent) has new properties ** Indwelling across a distributed community of practice, creating a networked imagination * We have to be careful when we develop AI, because data and algorithms operate as black boxes especially in deep learning systems. ** [[This becomes more and more an important aspect of augmenting our capabilities|The Black Box problem with Machine Learning and AI]] * A social-systems analysis is needed that draws on philosophy, law, sociology, anthropology, science and technology studies – especially wrt the curation of the data used to train these deep learning systems. ** “Only by asking broader questions about the impacts of AI can we generate a more holistic and integrated understanding…” -- Kate Crawford & Ryan Calo !!!!And he concludes: * Our challenge today is one of sense making in a world that won’t stay stable for our standard sense-making strategies to be effective. * Most of our pressing problems are wicked, our tools are increasingly opaque, our models and frames are outdated * We need to escape the tyranny of the present and meet head on the crisis of imagination. ---- ^^1^^ - Ursula K. Le Guin (in 2002) talked about the [[criticality and uniqueness of human imagination|The importance of imagination - Ursula K. Le Guin]]
From Edge's question [[What's your law?|https://www.edge.org/responses/whats-your-law]]: By Sherry Turkle (Abby Rockefeller Mauzé Professor of the Social Studies of Science and Technology, MIT; Internet Culture Researcher; Author, Reclaiming Conversation) ''Turkle's Law of Evocative Objects'': Every technology has an instrumental side, what the technology does for us and a subjective side, what the technology does to us, to our ways of seeing the world, including to our ways of thinking about ourselves. So the Internet both facilitates communication and changes our sense of identity, privacy, and sexual possibility; gene sequencing both gives us new ways of diagnosing and treating disease and new ways of thinking about human nature and human history. On an instrumental level, interactive, "sociable" robotics offers new opportunities for education, childcare, and eldercare; on a subjective level, it offers new challenges to our view of human nature, and to our moral sense of what kinds of creatures are deserving of relationship. ''Turkle's Law of Human Vulnerability to An Active Gaze'': If a creature, computational or biological, makes eye contact with a person, tracks her gaze, and gestures with interest toward her, that person will experience the creature as sentient, even capable of understanding her inner state. The human has evolved to anthropomorphize. We are on the brink of creating machines so "sociable" in appearance that they will push our evolutionary buttons to treat them as kindred. Yet they will not have shared our human biological and social experience and will thus not have our means of access to the meanings of moments in the human life cycle: a child's first step, an adolescent's strut, a parent's pride. Yet we will not be in complete control of our feelings for these objects because our feelings will not be based on what they know or understand, but on what we "experience" them as knowing, a very different thing. We don't know what people and animals are "really" thinking but grant them a "species pass" in which we make assumptions about their inner states. It is a social and moral contract. Contemporary technology has put us close to the moment when we shall be called upon to make this kind of contract (or some other kind) about creatures of our own devising. We are called upon to answer the question: What kinds of relationships are appropriate to have with a machine? Our answer will not only affect the instrumental roles that we allow technology to play but the way technology will co-create the human psyche and sensibility of the future.
I am still occasionally thinking about [[the plagiarism incident|I have a Bionic Ear]] I had recently in my CS class. Copying/plagiarism is enabled by the fact that I allow students to look at each other's programs as part of their learning, and before they are required to turn their assignment in for grading. I recently came across [[an article in The Atlantic Magazine|http://www.theatlantic.com/technology/archive/2011/06/how-i-failed-failed-and-finally-succeeded-at-learning-how-to-code/239855/]] by [[James Somers|http://www.theatlantic.com/author/james-somers/]], which very succinctly explains why letting "budding programmers" (as well as experienced ones) look at other people's code is "a very good thing". It completely reflects my beliefs and experience, both as a teacher and programmer, and reinforces my decision to keep encouraging students to look at other students' code as part of their learning. >Let's say that your sink is broken, maybe clogged, and you're feeling bold -- instead of calling a plumber you decide to fix it yourself. It would be nice if you could take a picture of your pipes, plug it into Google, and instantly find a page where five or six other people explained in detail how they dealt with the same problem. It would be especially nice if once you found a solution you liked, you could somehow immediately apply it to your sink. >Unfortunately that's not going to happen. You can't just copy and paste a Bob Vila video to fix your garage door. >But the really crazy thing is that this is what programmers do all day, and the reason they can do it is because code is text. >I think that goes a long way toward explaining why so many programmers are self-taught. Sharing solutions to programming problems is easy, perhaps easier than sharing solutions to anything else, because the medium of information exchange -- text -- is the medium of action. Code is its own description. There's no translation involved in making it go. >Programmers take advantage of that fact every day. The Web is teeming with code because code is text and text is cheap, portable and searchable. Copying is encouraged, not frowned upon. The neophyte programmer never has to learn alone. I see it all the time: by engaging with projects and being exposed to (and actively seeking) different approaches and solutions, the students are picking up the concepts and skills I want them to learn. Obviously, students need to be taught and need to understand the difference between learning from an example, acknowledging their sources, improving on the solution, versus blatantly, uncritically copying something and misrepresenting a solution as their own when it's not so. But even Albert Einstein acknowledged that "Example isn't another way to teach, it is the only way to teach."
I received an invitation via email to encourage my students to sign on to a site and start solving math challenges (puzzles) to sharpen their math and reasoning skills. The first (out of 100) challenges was as follows: [img[billiards ball math challenges|./resources/billiard ball challenge 1.png][./resources/billiard ball challenge.png]] You can obviously solve this puzzle through math/geometry (an exercise left to the reader :) But you could also write a small simulation program, to let it figure the answer out. I decided to use Scratch, since it has most of the basic building blocks (ha!) already built-into the language/environment. So here is the simulation program listing in Scratch (__don't__ [[run the simulation|https://scratch.mit.edu/projects/163532404/#fullscreen]] and/or look/scroll down if you want to try and figure out the answer on your own!) [img[billiards ball Scratch program|./resources/Scratch for billiard ball q 1.png][./resources/Scratch for billiard ball q.png]] And the answer is that the billiards ball will end up in pocket A (see picture/question above): [img[billiards ball Scratch program|./resources/Scratch for billiard ball a.png]]
A simple question with a simpler answer (click on the image to view :) [img[find x|./resources/find x 1.png][./resources/find x.png]] Worthy problem (a la [[Grooks (form of poetry)|http://www.archimedes-lab.org/grooks.html]] by Piet Hein)? >Problems worthy of attack >prove their worth by hitting back. (or the computer science equivalent: the problem with troubleshooting is that sometimes trouble shoots back.)
From an excellent lecture by Judea Pearl titled [["The Art and Science of Cause and Effect" |http://bayes.cs.ucla.edu/BOOK-2K/causality2-epilogue.pdf]] (see [[my review|On The Art and Science of Cause and Effect - Judea Pearl]]) and also Pearl's [["Comment: Understanding Simpson’s Paradox"|https://pdfs.semanticscholar.org/d2fa/2d0285e60a29a24a74568a1010328c46fa59.pdf]]: >Simpson’s paradox, first noticed by Karl Pearson in 1899, concerns the disturbing observation that every statistical relationship between two variables may be reversed by including additional factors in the analysis. For example, you might run a study and find that students who smoke get higher grades; however, if you adjust for age, the opposite is true in every age group, that is, smoking predicts lower grades. If you further adjust for parent income, you find that smoking predicts higher grades again, in every age–income group, and so on. Or another example: >The classical case demonstrating Simpson’s paradox took place in 1975, when ~UC-Berkeley was investigated for sex bias in graduate admission. In this study, overall data showed a higher rate of admission among male applicants; but, broken down by departments, data showed a slight bias in favor of admitting female applicants. The explanation is simple: female applicants tended to apply to more competitive departments than males, and in these departments, the rate of admission was low for both males and females. > >[img[fish nets|resources/fish nets.png]] >To illustrate this point, imagine a fishing boat with two different nets, a large mesh and a small net. A school of fish swim toward the boat and seek to pass it. The female fish [which are smaller in size] try for the small-mesh challenge, while the male fish [which are larger] try for the easy route. The males go through and only females are caught. Judging by the final catch, preference toward females is clearly evident. However, if analyzed separately, each individual net would surely trap males more easily than females. From the article [["The Role of Exchangeability in Inference"|https://projecteuclid.org/download/pdf_1/euclid.aos/1176345331]] by D. V. Lindley and Melvin R. Novick: Consider the data in Table 1 where 40 patients were given a treatment, T, and 40 assigned to a control, T*. The patients either recovered, R, or did not, R*. We are not considering small-sample problems so that the reader can if he wishes imagine all the numbers multiplied by 10,000, say. It is then clear that the recovery rate for patients receiving the treatment at 50% exceeds that for the control at 40% and the treatment is apparently to be preferred. However, the sex of the patients was also recorded and Table 2 gives the breakdown of the same 80 patients with sex, M male or M* female, included. It will now be seen that the recovery rate for the control patients is 10% higher than that for the treated ones, both for the males and the females. Thus, what is good for the men [i.e., no treatment] is good for the women, but bad for the population as a whole. We refer to this as Simpson's (1951) paradox, though it occurs in Cohen and Nagel (1934). In Appendix 1 we describe the situation mathematically and show that the paradox can only arise if, R and T being positively associated, M is positively associated both with R and with T. This is exactly what has happened here: The males have been mostly assigned to the treated group, the females to the control; perhaps because the doctor distrusted the treatment and so was reluctant to give it to the females where the recovery rate is much lower than for males. Alternatively expressed, treatment and sex have been confounded. Nevertheless it comes as a surprise to most people to learn that confounding can actually reverse an effect; here from +10% to -10%. An important problem posed by the paradox is this: Given a person of unknown sex would you expect the control or the treatment to be the more effective? (If having an unknown sex seems odd replace M and M* by a dichotomy that is difficult to determine, such as a genetic classification.) The answer seems clear that, despite Table 1, the control [i.e., no treatment] is better. If so, then this warns us to be very careful in using results like those in Table 1 to draw the opposite conclusions for could there not exist a factor, here sex, which reversed the conclusion? But is the answer so clear? Keeping the numbers the same, imagine data with T and T* replaced by white and black varieties of a plant respectively, and R and R* corresponding to high and low yields; the confounding factor being whether the plant grew tall, M, or short, M*. The white variety is 10% better overall, but 10% worse among both tall and short plants. In this case the white variety, T, seems the better one to plant; whereas T*, the control, was intuitively preferred in the medical situation. <html> <table> <tr><td><h2>People</h2></td><td><center>Table 1</center></td><td></td></tr> <tr><td><b>Total Population</b></td> <td>recovered (R)</td> <td>not recovered (R*)</td> <td>total</td> <td>recovery rate</td></tr> <tr><td>treated (T)</td> <td>20</td> <td>20</td> <td>40</td> <td>0.5</td></tr> <tr><td>not treated (T*)</td> <td>16</td> <td>24</td> <td>40</td> <td>0.4</td></tr> <tr> <td>total</td> <td>36</td> <td>44</td> <td>80</td> </tr> <tr><td></td><td><center>Table 2</center></td><td></td></tr> <tr><td><b>Males (M)</b></td> <td>recovered (R)</td> <td>not recovered (R*)</td> <td>total</td> <td>recovery rate</td></tr> <tr><td>treated (T)</td> <td>18</td> <td>12</td> <td>30</td> <td>0.6</td></tr> <tr><td>not treated (T*)</td> <td>7</td> <td>3</td> <td>10</td> <td>0.7</td></tr> <tr><td>total</td> <td>25</td> <td>15</td> <td>40</td> </tr> <tr><td></td></tr> <tr><td><b>Females (M*)</b></td> <td>recovered (R)</td> <td>not recovered (R*)</td> <td>total</td> <td>recovery rate</td></tr> <tr><td>treated (T)</td> <td>2</td> <td>8</td> <td>10</td> <td>0.2</td></tr> <tr><td>not treated (T*)</td> <td>9</td> <td>21</td> <td>30</td> <td>0.3</td> <tr><td>total</td> <td>11</td> <td>29</td> <td>40</td> </tr> </table> </html> The paradox as defined by Lindley and Novick is: >The apparent [(but illogical) conclusion] is, that when we know that the gender of the patient is male or when we know that it is female we do not use the treatment, but if the gender is unknown we should use the treatment! Obviously that conclusion is ridiculous. And Pearl observes (about the importance of context, and exterior/extra non-statistical considerations): >[Lindley and Novick] showed that, with the very same data, we should consult either the combined table or the disaggregated tables, depending on the context. Clearly, when two different contexts compel us to take two opposite actions based on the same data, our decision must be driven not by statistical considerations, but by some additional information extracted from the context. <html> <table> <tr><td><h2>Plants</h2></td><td><center>Table 1</center></td><td></td></tr> <tr><td><b>All Plants</b></td> <td>high yield (R)</td> <td>low yield (R*)</td> <td>total</td> <td>yield</td></tr> <tr><td>white (T)</td> <td>20</td> <td>20</td> <td>40</td> <td>0.5</td></tr> <tr><td>black (T*)</td> <td>16</td> <td>24</td> <td>40</td> <td>0.4</td></tr> <tr> <td>total</td> <td>36</td> <td>44</td> <td>80</td> </tr> <tr><td></td><td><center>Table 2</center></td><td></td></tr> <tr><td><b>Grew Tall (M)</b></td> <td>high yield (R)</td> <td>low yield (R*)</td> <td>total</td> <td>yield</td></tr> <tr><td>white (T)</td> <td>18</td> <td>12</td> <td>30</td> <td>0.6</td></tr> <tr><td>black (T*)</td> <td>7</td> <td>3</td> <td>10</td> <td>0.7</td></tr> <tr><td>total</td> <td>25</td> <td>15</td> <td>40</td> </tr> <tr><td></td></tr> <tr><td><b>Grew Short (M*)</b></td> <td>high yield (R)</td> <td>low yield (R*)</td> <td>total</td> <td>yield</td></tr> <tr><td>white (T)</td> <td>2</td> <td>8</td> <td>10</td> <td>0.2</td></tr> <tr><td>black (T*)</td> <td>9</td> <td>21</td> <td>30</td> <td>0.3</td> <tr><td>total</td> <td>11</td> <td>29</td> <td>40</td> </tr> </td> </tr> </table> </html>
Arthur C. Clarke wrote a 31-word (thirty one words!) short story^^1^^ called "siseneG," as in "Genesis" reversed. As of March 1984, it was the only one he'd written in nearly ten years^^2^^. The tale, in its entirety: > > And God said: DELETE lines One to Aleph^^3^^. LOAD. RUN. > And the Universe ceased to exist. > > Then he pondered for a few aeons, sighed, and added: ERASE. > It never had existed. """ """ (compare to [[In the Beginning was the Command Line - by Neal Stephenson]]). ---- ^^1^^ compare to [[Hemingway’s famous six-word tale|https://en.wikipedia.org/wiki/For_sale:_baby_shoes,_never_worn]], “For sale: baby shoes, never worn.” (this “six word story”^^4^^ story/urban legend inspired [[a website dedicated to these stories|http://www.sixwordstories.net/]]) ^^2^^ - Clarke accompanied this story with a letter/preface to his publisher: >This is the only short story I've written in ten years or so. > >I think you'll agree that they don't come much shorter. > >(Signed, 'Arthur C Clarke') > >21 Mar 84 ^^3^^ - [[Aleph|https://en.wikipedia.org/wiki/Aleph_number]] (presumably subscript 0, as in Aleph,,0,,) is the first infinite set in an infinite set of infinites (Aleph,,1,,, Aleph,,2,,, and so on). ^^4^^ - I use Hemingway's anecdote as inspiration for students to program their own "Six Words (or more :) Story" (in [[Scratch|https:scratch.mit.edu]]) about an (hopefully interesting :) aspect of their lives. ^^5^^ - in case you are paying attention, the footnotes happen to be much longer^^6^^ than Clarke's 31-word story they are about :) ^^6^^ - but the footnotes here, fortunately, don't fall into the "trap"^^7^^ seen (experienced?) in footnotes in novels like //Infinite Jest//^^8^^ (by David Foster Wallace) and //House of Leaves// (by Mark Z. Danielewski) where they operate in entirely different ways. In Infinite Jest, the footnotes seem at first to function solely as universe-expanding background information. As the novel progresses, they become longer and more complex—eventually even the footnotes have footnotes—until we hit the infamous Footnote 324, which is seven pages of small type the length of an entire chapter if printed in normal-sized font. The footnotes in Infinite Jest are so numerous and varied in content, some of them begin to take on a wholly separate nature, more or less a parallel narrative that tells its own story. ^^7^^ - "trap" is a loaded (and opinionated) word, so as a counter balance, here is a counter argument [[in praise of using footnotes|https://openscholarship.wustl.edu/cgi/viewcontent.cgi?article=1597&context=law_lawreview]] (and a [[local GD copy|https://drive.google.com/open?id=1pVIgtdD_iGJVzqC1y7vLJ-ckKiYp4-nL]]). ^^8^^ - OK, enough jest (not to be confused by //Infinite Jest//) already! :)
lifelong, spiraling discovery and learning
Full-Mindedness and Mind-Fullness
On a recent flight, I watched the movie "Sliding Doors" (1998) with Gwyneth Paltrow and John Hannah. I had actually watched it years ago, so it was a deja-vu in the literal sense (albeit not an encounter of the 2nd kind ;-), but wanted to watch it again, since (spoiler alert!): (a) the idea of parallel life tracks has always been appealing (to me, and to many others as well) (b) I was sure I missed some points in the plot in the first viewing, due to the fact that one has to keep in mind the two tracks, as the movie switches between them, and (c) I find it fascinating how a small variation or event in life, as insignificant as it may seem, can have major implications and impacts over time; the movie is all about a case like this. This last point emphasizes the importance, or at least the potential for a big impact, of what we perceive as serendipity on this "strange and complex process" we call life. And so, as it happens (how exactly?), I was reading on this flight (!) the very interesting book [[Complexity - a guided tour|resources/Melanie-Mitchell-Complexity_a-guided-tour-366-pages.pdf]]^^1^^ by Melanie Mitchell, who did her ~PhD under [[Douglas Hofstadter]], and had worked on the [[Copycat|http://en.wikipedia.org/wiki/Copycat_%28software%29]] analogy-making system as part of her studies. In the book, in the chapter covering chaos, she writes: >The defining idea of chaos is that there are some systems -- //chaotic// systems -- in which even miniscule uncertainties [in conditions or parameters] can result in huge errors in long-term predictions of these [conditions or parameters]. This is known as "sensitive dependence on initial conditions". Life can definitely be called "chaotic" given the above "defining idea". In the movie, the protagonist (Paltrow) gets fired from her job, rushes to catch a train (the London Tube), and in one track of the storyline, ends up missing it by a fraction of a second due to a little girl obstructing her way, and in the other storyline track, ends up catching the train. The fact that the train's (sliding) doors closed in her face (in one track) vs. her ability to "slide through the sliding doors" (in the second track) makes a huge difference in the protagonist's life moving forward, and the movie makes the point of systems (here, life) having "sensitive dependence on initial conditions" very clear and convincing (and fun to watch). ''So why is all this loopy serendipity?'' For one, the serendipitous path that led to this deja-vu film watching on the plan goes (more or less) like this: * I had watched the film years ago, and it stuck with me, mainly because of point (a) above. I've liked sci-fi literature as well as physics for many years, and parallel tracks and universes (including the "extraordinary" possibilities which open up by time travel -- scientific and/or fictional) have interested me for a long time. * In parallel (ha!), I have been interested in and reading books on cognition and artificial intelligence, and read several books by Douglas Hofstadter (the first one which I read in the 80's was the Pulitzer prize winner //Gödel, Escher, Bach: An Eternal Golden Braid//). * That book led me to reading //Fluid Concepts and Creative Analogies: Computer Models of the Fundamental Mechanisms of Thought// by him, where he mentions the [[Copycat|http://en.wikipedia.org/wiki/Copycat_%28software%29]] analogy-making system, and his collaborator (student and mentee) [[Melanie Mitchell|http://en.wikipedia.org/wiki/Melanie_Mitchell]]. * I recently started thinking about teaching a [[Citizen Schools course|http://tinyurl.com/HaggaiLDT]], called //Simplexity//, about simple rules leading to complex behaviors, and determinism which may lead to chaos (rings a bell?), and started searching for books on complexity and complex systems, and hit on Melanie Mitchell's book [[Complexity - a guided tour|resources/Melanie-Mitchell-Complexity_a-guided-tour-366-pages.pdf]]^^1^^, which I took with me to read on the plane. * Mitchell's book covers chaos and chaotic systems, and it was only a simple analogy (pun intended) from that to life, it's sensitivity to initial (and sometimes seemingly insignificant) initial conditions, and the great depiction of it in the movie Sliding Doors. * So, adding one and one together or two and two (or more) for that matter: fascination with parallel tracks in life, life as a chaotic system, fascination with cognition, Hofstadter's work in this area, him working with Mitchell, who writes ([[and teaches|http://web.cecs.pdx.edu/~mm/#Courses]]) about complex systems and chaos, and __other things__^^2^^, and voila, I've ended up with her book on the plane, re-watching Sliding Doors during that flight, after watching it many years ago. And now for the serendipitous loop within a loop (talking about [[strange loops|http://en.wikipedia.org/wiki/I_Am_a_Strange_Loop]]): as is obvious from the [[reference to infinite state machines|About me]], I like state machines and [[Cellular Automata|Cellular Automaton Rule 110]], which fascinated Stephen Wolfram, whose book //A New Kind of Science// is [[reviewed by Melanie Mitchell|resources/Mitchell-Wolfram-new-kind-of-science-review.pdf]]^^3^^, who wrote the book on Complexity, who I've read in preparation for a [[Citizen Schools course|http://tinyurl.com/HaggaiLDT]] (called Simplexity) on simple/deterministic rules (like the ones in Conway's Game of Life) leading to complex/chaotic behavior. ---- ^^1^^ retrieved from [[Sorrentino's blog|http://www.waltersorrentino.com.br/wp-content/uploads/2012/02/Melanie-Mitchell-Complexity_a-guided-tour-366-paginas.pdf]] ^^2^^ Mitchell also writes about Conway's Game of Life, and [[reviews Wolfram's New Kind of Science|resources/Mitchell-Wolfram-new-kind-of-science-review.pdf]]^^3^^ ^^3^^ retrieved from [[Mitchell's website|http://web.cecs.pdx.edu/~mm/new-kind-of-science-review.pdf]]
In 1980 [[Alan Kay|https://en.wikipedia.org/wiki/Alan_Kay]] (a "[[CS Sage|https://en.wikipedia.org/wiki/List_of_computer_scientists]]") created Smalltalk and invented the term "Object Oriented." When asked what that means he replied, "Smalltalk programs are just objects." When asked what objects are made of he replied, "objects." When asked again he said "look, it's all objects all the way down. Until you reach turtles." This is in reference to the "mythical" story which has been circulating for years. Stephen Hawking in one of his books tells it this way: A bigname scientist was giving a lecture on astronomy. After the lecture, an elderly lady came up and told the scientist that he had it all wrong. "The world is really a flat plate supported on the back of a giant turtle" she said. The scientist asked "And what is the turtle standing on?" To which the lady triumphantly replied: "You're very clever, young man, but it's no use -- it's turtles all the way down." And here is what Richard Feynman had to say about the [[turtles explanation (among other things)|https://www.brainpickings.org/2013/07/19/richard-feynman-science-morality-poem/]]: >We have been led [by science findings] to imagine all sorts of things infinitely more marvelous than the imaginings of poets and dreamers of the past. It shows that the imagination of nature is far, far greater than the imagination of man. For instance, how much more remarkable it is for us all to be stuck — half of us upside down — by a mysterious attraction, to a spinning ball that has been swinging in space for billions of years, than to be carried on the back of an elephant supported on a tortoise swimming in a bottomless sea.
A small gem by [[Kai Krause|http://edge.org/memberbio/kai_krause]] on [[Edge|http://edge.org/]]. Also worth checking [[Kai's website|http://www.byteburg.de/]] There is a deep fascination I have been carrying with me for decades now, ever since earliest childhood: the interplay between simplicity and complexity. Unable to express it verbally at the time, in hindsight it seems clear: they are all about that penultimate question: what is life and how did this world come into existence? In many stages and phases I discovered a multitude of ideas that are exactly what is called for here: deep, elegant and beautiful explanations of the principles of nature. Simplicity is embodied in a reductionist form in the ~YinYang symbol: being black or white. In other familiar words: To be or not to be. Those basic elements combined: that is the process spawning diversity, in myriads of forms. As a youngster I was totally immersed in 'Lego' blocks. There are a handful of basic shapes (never liked the 'special' ones and clamored instead for a bigger box of basics) and you could put them together in arrangements that become houses, ships, bridges...entire towns I had growing up the sides of my little room to the tops of wardrobes. And I sensed it then: there is something deep about this. A bit later I got into a mechanical typewriter (what a relief to be able to type clearly, my handwriting had always been horrid the hand not being able to keep up with the thinking... and relished the ability to put together words, sentences, paragraphs. Freezing a thought in a material fashion, putting it on paper to recall later. What's more to let someone else follow your thinking! I sensed: this is a thing of beauty. Then I took up playing the piano. The embryonic roots of the software designer of later decades probably shuddered at the interface: 88 unlabeled keys! Irregular intervals of black ones interspersed... and almost the exact opposite of todays "we need to learn this in one minute and no, we never ever look at manuals" attitude. It took months to make any sense of it, but despite the frustrations, it was deeply fascinating. String together a few notes with mysterious un-definable skill and out comes... deeply moving emotion? So the plot thickens: a few Lego blocks, a bunch of lettershapes or a dozen musical notes... and you take that simplicity of utterly lame elements, put them together...and out pops complexity, meaning, beauty. Later in the early 70s I delved into the very first generation of large synthesizers and dealt specifically with complex natural sounds being generated from simple unnatural ingredients and processes. By 1977 now in California it was computer graphics that became the new frontier and again: seemingly innocent little pixels combine to make ... any image as in: anything one can imagine. Deep. In those days I also began playing chess, and carom billiards simple rules, a few pieces, 3 balls...but no game is ever the same. Not even close. The most extreme example of this became another real fascination: the game of GO. Just single moves of black and white stones, on a plain grid of lines with barely a handful of rules but a huge variety of patterns emerges. Elegant. The earliest computing, in the first computer store in the world, Dick Heyser in Santa Monica, had me try something that I had read in SciAm by Martin Gardner: Conway's 'Game of Life'. The literal incarnation of the initial premise: Simplicity reduced to that YinYang: a cell is On or Off, black or white. But there is one more thing added here now: iteration. With just four rules each cell is said to live or die and in each cycle the pattern changes, iteratively. From dead dots on paper, and static pixels on phospor, it sprang to life! Not only patterns, but blinkers, gliders, even glider guns, heck glider gun canons! Indeed, it is now seen as a true Turing-complete machine. Artificial Life. Needless to say: very deep. Another example in that vein are of course fractals. Half an inch of a formula, when iterated, is yielding worlds of unimaginably intricate shapes and patterns. It was a great circle closing after 20 years for me to re-examine this field, now flying through them as "frax" on a little iPhone, in realtime and in real awe. The entire concept of the computer embodies the principles of simple on/off binary codes, much like YinYang, being put together to form still simplistic gates and then flip-flops, counters, all the way to RAM and complex CPU/GPUs and beyond. And now we have a huge matrix computer with billions of elements networked together (namely 'us', including this charming little side corridor called 'Edge'), just a little over 70 years after Zuse's Z3 we reached untold complexity with no sign of slowing down. Surely the ultimate example of 'simplexity' is the genetic code four core elements being combined by simple rules to extreme complex effect the DNA to build archaea, felis or homo somewhat sapiens. Someone once wrote on Edge "A great analogy is like...a diagonal frog" which embodies the un-definable art of what constitutes a deep, beautiful or elegant explanation: Finding the perfect example! The lifelong encounters with "trivial ingredients turning to true beauty" recited here are in themselves neither terse mathematical proofs nor eloquently worded elucidations (such as one could quote easily from almost any Nobel laureate's prize-worthy insights). Instead of the grandeur of 'the big formulas' I felt that the potpourri of AHA! moments over six decades may be just as close to that holy grail of scientific thinking: to put all the puzzle pieces together in such away that a logical conclusion converges further on... the truth. And I guess one of the pillars of that truth, in my eyes, is the charmingly disarmingly miniscule insight: "So much from so little. Now that explains a lot!"
My first reaction to the //name// of the [[organization/website|https://software-carpentry.org/]] was somewhat negative. On an intuitive level, I think that likening software development to carpentry is probably a good enough description/analogy (and a sad testament to the state of this budding discipline :( , but I felt (again, we are talking about the initial intuitive response here) that since (I believe) that the aspiration is to get out of this sorry state (where one has to write and re-create desired functionality, one character at a time), and therefore picking an aspirational, forward-looking, visionary title/name would be much preferred. But, I think that what I've seen so far on the site is pretty solid, useful, and practical, so maybe the name reflects the focus: factual, practical, hard-nosed effectiveness. Their tagline "TEACHING LAB SKILLS FOR SCIENTIFIC COMPUTING" may point in the same direction I have been advocating under teaching [[Computational Thinking/Literacy (and skills)|A Framework for Computational Thinking, Computational Literacy]]. !!! From their presentation about their [[Lessons Learned|http://swcarpentry.github.io/slideshows/lessons-learned/index.html]] * The opening slide is both innovative, funny, and deep: ** If you build a man a fire, you'll keep him warm for a night. If you set a man on fire, you'll keep him warm for the rest of his life. *** Which is not as macabre as it looks at first! It really preserves the original (and similarly constructed) quote about the giving fish vs. teaching to fish. It plays (I think) on the quote about learners are not vessels to be filled, but wood to be lighted :) * Lesson #1 - Most researchers think programming is a tax they have to pay to do science. ** "If I wanted to be a computer scientist, I would have picked a different major in undergrad." * Lesson #4 - The curriculum is full. "What do I drop to make room for more computing: quantum or thermo?" ** But, 5 minutes (of Computation) per lecture ⇒ 4 courses in a degree ** Have to fit in around the curriculum until we achieve critical mass * Lesson #9 - Most people would rather fail than change. ** Most scientists treat research on teaching and programming like most politicians treat research on climate change. !!! Research/Pedagogy Background/Foundation They base their pedagogy and focus on Mark Guzdial's research (Georgia Tech), and as captured on [[his blog|http://computinged.wordpress.com/]]. For example: * [[Subgoals improve performance|https://computinged.wordpress.com/2012/06/05/instructional-design-principles-improve-learning-about-computing-making-measurable-progress/]] * [[Practice works best for facts, worked examples for skills|https://computinged.wordpress.com/2012/04/04/practice-is-better-for-learning-facts-worked-examples-are-better-for-learning-skills/]] * [[Peer instruction beats lecture|https://computinged.wordpress.com/2013/01/15/ucsds-overwhelming-argument-for-peer-instruction-in-cs-classes/]] * Media-first increases retention
The "[[CS Sage|https://en.wikipedia.org/wiki/List_of_computer_scientists]]" [[Fred Brooks|https://en.wikipedia.org/wiki/Fred_Brooks]] (of [[The Mythical Man Month|https://archive.org/stream/mythicalmanmonth00fred/mythicalmanmonth00fred_djvu.txt]] fame), wrote a thoughtful article after receiving the //first// ACM [[Allen Newell|https://en.wikipedia.org/wiki/Allen_Newell]] Award (named after another CS Luminary/Sage) in 1994, sharing his thoughts about the [[Computer Scientist as a Toolsmith|http://www.cs.unc.edu/~brooks/Toolsmith-CACM.pdf]].
In the article he talks about "The Gift of Subcreation", (which could be interpreted to include tool and app creation, Artificial Life, and other software models and creations) and observes^^1^^:
>Making things has its glories and joys, and they are different from those of the mathematician and those of the scientist.
Brooks quotes a poem by J.R.R. Tolkien about those human, virtual creations ("subcreations"):
>Although now long estranged,
>Man is not wholly lost nor wholly changed,
>Dis-graced he may be, yet is not de-throned,
>and keeps the rags of lordship once he owned:
>Man, Sub-creator, the refracted Light
>through whom is splintered from a single White
>to many hues, and endlessly combined
>in living shapes that move from mind to mind.
>Though all the crannies of the world we filled
>with Elves and Goblins, though we dared to build
>Gods and their houses out of dark and light,
>and sowed the seed of dragons—’twas our right
>(used or misused). That right has not decayed;
>we make still by the law in which we’re made.
----
^^1^^ See what Brooks says about [[The Software Scientist as a Toolsmith]]
From Pete Goodliffe's book //Becoming a Better Programmer// ([[Software Development is|resources/Goodliffe - Becoming a Better Programmer.docx]]): ''Software Development is ... an Art'' since it is: * creative * aesthetic * mechanical * team-based ''Software Development is ... a Science'' since it is: * rigorous * systematic * insightful ''Software Development is ... a Sport'' since it involved: * teamwork * discipline * rules ''Software Development is ... a Child's Play'' since it involves: * learning * simplicity * having fun ''Software Development is ... a Chore'' since it requires: * clean up * work in the background * maintenance
Jeff Dean facts^^1^^ aren’t, well, true. But the fact that someone went to the trouble to make up Chuck Norris-esque exploits about Dean is remarkable. That’s because Jeff Dean is a software engineer (and now the head of Google Brain), and software engineers are not like Chuck Norris. For one thing, they’re not lone rangers—software development is an inherently collaborative enterprise. For another, you have to be somewhat of a computer geek to understand most of the jokes that people tell about Jeff Dean (unlike Chuck's :). Nevertheless, on April Fool’s Day 2007, some admiring young Google engineers saw fit to bestow upon Jeff Dean the honor of a website extolling his programming achievements. For instance: * Compilers don’t warn Jeff Dean. Jeff Dean warns compilers. * Jeff Dean writes directly in binary. He then writes the source code as documentation for other developers. * When Jeff Dean has an ergonomic evaluation, it is for the protection of his keyboard. * Jeff Dean was forced to invent asynchronous ~APIs one day when he optimized a function so that it returned before it was invoked. * Jeff Dean compiles and runs his code before submitting, but only to check for compiler and CPU bugs. * Jeff Dean once failed a [[Turing test|https://plato.stanford.edu/entries/turing-test/]] when he correctly identified the 203rd Fibonacci number in less than a second. * The speed of light in a vacuum used to be about 35 mph. Then Jeff Dean spent a weekend optimizing physics. * Jeff Dean was born on December 31, 1969 at 11:48 PM. It took him twelve minutes to implement his first time counter. (referring to [[Unix Epoch Time|https://en.wikipedia.org/wiki/Unix_time]]: 00:00:00 Coordinated Universal Time (UTC), Thursday, 1 January 1970) * [and also:] ** Jeff Dean's watch displays seconds since January 1st, 1970. He is never late. * Jeff Dean eschews both Emacs and VI. He types his code into [[zcat|https://linux.die.net/man/1/zcat]], because it's faster that way [due to the ~Lempel-Ziv compression]. * When Jeff Dean sends an Ethernet frame there are no collisions because the competing frames retreat back up into the buffer memory on their source NIC [Network Interface Card (hardware)]. *Unsatisfied with constant time, Jeff Dean created the world's first O(1/n) algorithm. * Once, in early 2002, when the search back-ends went down, Jeff Dean answered user queries manually for two hours. Result quality improved markedly during this time. * The rate at which Jeff Dean produces code jumped by a factor of 40 in late 2000 when he upgraded his keyboard to USB2.0. * Jeff Dean wrote an O(n^^2^^) algorithm once. It was for the [[Traveling Salesman Problem|http://www.csd.uoc.gr/~hy583/papers/ch11.pdf]] [the [[brute force solution can be of O(n!) complexity!!!|http://poincare101.blogspot.co.il/2012/04/travelling-salesman-problem.html]]. [[Dynamic programming can yield|https://www.explainxkcd.com/wiki/index.php/399:_Travelling_Salesman_Problem]] O(n^^2^^ * 2^^n^^)) . The implication is that Dean implemented an "inefficient ( O(n^^2^^) algorithm only once in his life ...]. * Jeff Dean once implemented a web server in a single printf() call. Other engineers added thousands of lines of explanatory comments but still don't understand exactly how it works. Today that program is the front-end to Google Search. * Jeff Dean can beat you at connect four. In three moves. * When your code has undefined behavior, you get a segmentation fault and corrupted data. When Jeff Dean's code has undefined behavior, a unicorn rides in on a rainbow and gives everybody free ice cream. * Jeff Dean is still waiting for mathematicians to discover the joke he hid in the digits of PI. * Jeff Dean's keyboard has two keys: 1 and 0. * When Graham Bell invented the telephone, he saw a missed call from Jeff Dean. *Jeff starts his programming sessions with 'cat > /dev/mem' [ see [[cat|http://www.linfo.org/cat.html]] and [[/dev/mem|http://superuser.com/questions/71389/what-is-dev-mem]] ] * One day Jeff Dean grabbed his ~Etch-a-Sketch instead of his laptop on his way out the door. On his way back home to get his real laptop, he programmed the ~Etch-a-Sketch to play Tetris. * Jeff Dean proved that P=NP when he solved all NP problems in polynomial time on a whiteboard. * Jeff Dean's PIN is the last 4 digits of pi. * When Jeff gives a seminar at Stanford, it's so crowded Don Knuth has to sit on the floor. (True) * Jeff Dean got promoted to level 11 in a system where max level is 10. (True) * Jeff Dean's resume lists the things he hasn't done; it's shorter that way. * To Jeff Dean, "NP" means "No Problemo". [ NP = [[nondeterministic, polynomial time|http://www.dictionary.com/browse/nondeterministic-polynomial-time]] ] * You don't explain your work to Jeff Dean. Jeff Dean explains your work to you. * Jeff Dean's resume has so many accomplishments, it has a table of contents [and an index]. * Jeff Dean doesn't exist, he's actually an advanced AI created by Jeff Dean. * Jeff Dean's [[IDE|https://en.wikipedia.org/wiki/Integrated_development_environment]] doesn't do code analysis, it does code appreciation. * Jeff Dean's keyboard doesn't have a Ctrl key because Jeff Dean is always in control. * When Jeff Dean says "Hello World", the world says "Hello Jeff". * Jeff Dean can get 1s out of [[/dev/zero|https://en.wikipedia.org/wiki//dev/zero]]. * Jeff Dean simply walks into [[Mordor.|http://www.urbandictionary.com/define.php?term=mordor&defid=2921558]] * When your code is killed by SIGJEFF, it never runs again. * Jeff Dean's calendar goes straight from March 31st to April 2nd; no one fools Jeff Dean. * Jeff Dean never has the wrong number; you have the wrong phone. * Errors treat Jeff Dean as a warning. * Jeff's code is so fast the assembly code needs three HALT opcodes to stop it. * Emacs' preferred editor is Jeff Dean. * Google: it's basically a Jeff Dean side project. * Jeff Dean has to unoptimize his code so that reviewers believe it was written by a human. * Jeff Dean doesn't need speakers or headphones. He just types "cat *.mp3", glances at the screen, and his brain decodes the music in the background while he works. * Knuth mailed a copy of TAOCP to Google. Jeff Dean autographed it and mailed it back. [ [[TAOCP|https://en.wikipedia.org/wiki/The_Art_of_Computer_Programming]] was actually written by [[Donald Knuth|https://en.wikipedia.org/wiki/Donald_Knuth]] ] ---- ^^1^^ Found mainly on [[Google+|https://plus.google.com/+KentonVarda/posts/TSDhe5CvaFe]], [[Slate|http://www.slate.com/articles/technology/doers/2013/01/jeff_dean_facts_how_a_google_programmer_became_the_chuck_norris_of_the_internet.html]], and [[Quora|https://www.quora.com/What-are-all-the-Jeff-Dean-facts]]
SOMETIMES Sometimes if you move carefully through the forest breathing like the ones in the old stories who could cross a shimmering bed of dry leaves without a sound, you come to a place whose only task is to trouble you with tiny but frightening requests conceived out of nowhere but in this place beginning to lead everywhere. Requests to stop what you are doing right now, and to stop what you are becoming while you do it, questions that can make or unmake a life, questions that have patiently waited for you, questions that have no right to go away. : -- from Whyte's site at [[Everything is waiting for you|http://www.davidwhyte.com/everything-is-waiting-for-you/]]
Garry Kasparov after playing (and losing) chess with IBM's Deep Blue mainframe computer said: Sometimes quantity becomes quality. [img[T-Shirt|resources/chess_game.jpeg][resources/chess_game.jpeg]] "I remember when you could only lose a chess game to a supercomputer." - New Yorker Cartoon, by: Avi Steinberg On the other hand ... [img[Kasparov beats deep blue|resources/Kasparov beats Deep Blue.png]]
Pleasure is the state of being brought about by what you learn. Learning is the process of entering into the experience of this kind of pleasure. No pleasure, no learning. No learning, no pleasure.
On interpretation, deduction, implication, inference, inuendo and other mental/emotional information processing activities: In his book [[The Most Human Human - by Brian Christian]] he quotes [[Douglas Hofstadter]] (from his book "Gödel, Escher, Bach: an Eternal Golden Braid"): >[We seem to have the notion that] isomorphisms and decoding mechanisms (i.e., information-revealers) simply reveal information which is intrinsically inside the structures, waiting to be "pulled out". >This leads to the idea that for each structure, there are certain pieces of information which can be pulled out of it, while there are other pieces of information which cannot be pulled out of it. But what does this phrase "pull out" really mean? How hard are you allowed to pull? There are cases where by investing sufficient effort, you can pull very recondite [obscure, complex] piece of information out of certain structures. >In fact, the pulling-out may involve such complicated operations that it makes you feel you are putting more information in than you are pulling out. This passage from [[the book|https://publicism.info/philosophy/human/10.html]] seems to me, is trying to point to the sometimes blurry (and dangerous, if crossing the) line between careful, cautious, fruitful, and creative knowledge extraction and learning, and fanciful, undisciplined, "innovative", vacuous "creations of the mind".
Type the text for 'New Tiddler'
!!!Zen and "Stepping Out" [>img[Fibonacci Curve|./resources/Fibonacci_spiral_1.jpg][./resources/Fibonacci_spiral.jpg]] >A Zen person is always trying to understand more deeply what he is, by stepping more and more out of what he sees himself to be, by breaking every rule and convention which he perceives himself to be chained by - needless to say, including those of Zen itself. Somewhere along this elusive path may come enlightenment. In any case (as I see it), the hope is that by gradually deepening one's self awareness, by gradually widening the scope of "the system", one will at the end come to a feeling of being at one with the entire universe. - Douglas Hofstadter in [[Gödel, Escher, Bach|http://en.wikipedia.org/wiki/G%C3%B6del,_Escher,_Bach]], p. 479
In a well researched article titled [[Instructional strategies and tactics for the design of introductory computer programming courses in high school|http://doc.utwente.nl/58656/1/Merrienboer87instructional.pdf]]^^1^^ Van Merrienboer and Krammer introduce different strategies and tactics for teaching beginners to program.
!!!The authors identify 3 common strategies or approaches to teaching programming:
* The Expert approach emphasizes on both algorithm and program design in a systematic top-down fashion. For this reason, students are offered problem specifications during the course that are characterized as non-trivial design problems.
* The Spiral approach emphasizes a stepwise incremental learning. Problem specifications that are presented to students during the course gradually become more complex in both the coding and the design aspects that they require. Consequently, in the beginning of the course students receive more or less trivial problems that emphasize syntactic and lower level semantic knowledge.
* The Reading approach emphasizes program comprehension, modification and amplification (and on a related note/skill, see [[A Helpful Guide to Reading Better - Farnam Street]]). For this reason, students are confronted with non-trivial design problems from the beginning of the course. However, these problems are presented in combination with their complete or partial solutions in the form of well-designed, well-structured and well-documented programs. The students' tasks gradually become more complex during the course, changing from using and analyzing programs, through modifying and extending programs, to independently designing and coding programs.
!!!The authors offer several tactics for teaching, with the goals and circumstances in mind:
* ''Concrete Computer Model'' - Students should be introduced and exposed to a concrete computer model (a-la "glass box approach"). They cite research that shows that this improves student program comprehension and generation.
** They make a distinction between a "black box approach" and a "glass box approach" in elementary programming. In the black box approach, students have no idea of what goes on inside the computer because they lack an adequate model. In the glass box approach, students do have such an idea because the instruction includes a concrete but simplified computer model. This model makes it possible to emphasize a "notional machine" on both a general level, such as in teaching the relationship between the terminal and the computer and a specific level, such as in teaching assignment statements.
* ''Design Diagrams/Plans/Schemas'' - Explicitly present design diagrams or schemas for solving problems and top-down decomposition of problems.
** Instructional materials may support such top-down processing by explicitly presenting a design diagram: A flow-chart or structured diagram prescribing in detail the actions and methods that ensure a systematic and effective design process. Equivalent design diagrams for solving elementary science problems are sometimes referred to as SAP-charts ("Systematic Approach to Problem-solving"). The presentation of a design diagram clarifies the complementary processes of successive refinement and top-down program design and facilitates the development of a general design schema.
* ''Worked-out Examples'' - In order to help students transition from learning declarative knowledge to practicing the desired procedural behavior, students should use concrete examples of problem solutions - related to the problem at hand - that have the form of concrete computer programs. These worked-out examples function as analogies, which students use as blue-prints or concrete schemata to map their new solutions. Thus, analogy is used to bridge the gap between the current declarative knowledge and the desired programming behavior. After students have gained more experience, their need for worked-out examples disappears, as a result of knowledge compilation.
* ''Annotated Examples'' - whereas the presentation of worked-out examples is important in its own right, the examples should be annotated with information about what they are supposed to illustrate. Annotated examples bear resemblance to programming plans: they both offer templates of code instead of unorganized factual information and they both slress the critical features in this template. But, whereas programming plans primarily serve to present new information concerning a template of programming code and its relationship with specific programming problems, annotated, worked-out examples serve as an analogy to support knowledge compilation. In fact, we think that __it is desirable to further annotate worked-out examples by explicitly referring to the programming plans they use__.
** Therefore, the recommendation is: present concrete, annotated, worked-out examples in the form of concrete pro- grams for well-described programming problems that are related to the problems at hand .
* ''Task Variation'' - there must be enough task variation in practice to develop a broad procedural knowledge base, which underlies flexibility in programming behavior on a high performance level.
** Some variation in elementary programming may be offered by (a) the assignment of different tasks, such as using the editor, comprehending pro- grams, designing algorithms, generating programs, debugging programs and so forth, and (b) the presentation of a broad range of both programming problems that have different underlying solutions in program generation and programs that are the solutions for different programming problems in program comprehension.
** offer variation in the different skills involved in computer programming and present a wide range of programming problems and programs. And, for worked-out examples, it is not only important to offer students some variation in problems and programs but it is also important to tell them what the critical features in these different problems and programs are.
* The authors have a cautionary note on top-down teaching strategies:
** top-down design techniques may minimize processing load for expert programmers but not for novices. Strictly speaking, top-down programming is possible if students have at each step available an appropriate set of productions as well as the necessary declarative knowledge. This only occurs if both the problem is of a familiar type and the student has experience with the programming language. When top-down programming is possible, it will minimize processing load; however, when it is not possible - as will often be the case for novices - it cannot prevent processing overload. Consequently, top-down programming in introductory programming courses may be desirable, but it is often not possible because the necessary knowledge is not available.
----
^^1^^ [[Local copy|resources/Merrienboer - CS instructional tactics.pdf]]
In an article titled [["New Pathways into Robotics: Strategies for Broadening Participation"|http://web.media.mit.edu/~mres/papers/NewPathwaysRoboticsLLK.pdf]], authors Natalie Rusk and Mitchel Resnick, write about a few guidelines/principles for broadening participation, which, I think, could be generalized to Computing and STEM education in general. In the paper introduction they write: >This paper examines strategies for introducing students to robotics technologies and concepts,and argues for the importance of providing multiple pathways into robotics, to ensure that thereare entry points to engage young people with diverse interests and learning styles. And the strategies/recommendations: * ''Focus on Themes (Not Just Challenges)'' - Instead of focusing on a single design challenge, we have found it valuable to structure workshops around a shared theme. * ''Combine Art and Engineering'' - An engineering assignment typically consists of a problem to solve. We have found that many young people become more engaged if they learn engineering concepts in the process of creating interdisciplinary projects that combine art and engineering. * ''Encourage Storytelling'' - cater to both “patterners” (learners most interested in patterns and structures) and “dramatists” (preferring pretend play and social interaction) (Shotwell, Wolf, & Gardner, (1979)) * ''Organize Exhibitions (Rather than Competitions)'' - Many activities are structured as competitions. Competitions are motivating for many students, but alienating for others. An alternative approach is to offer young people the opportunity to display their work in an exhibition rather than a competition.
.viewer table.borderless,.viewer table.borderless * {border: 0;}
Unlike [[Wislawa Szymborska's angle on the statistics of life|A Word On Statistics - Wislawa Szymborska]], [[David Eagleman|http://eagleman.com/]] has a book called //Sum: Forty Tales from the Afterlives// (see [[excerpt from a story called ''Metamorphosis''|http://eagleman.com/sum/excerpt]]), where he spins an afterlife scenario which highlights the preciousness of life using a different type of "statistics" (or maybe "probability"). It is intriguing/thought-provoking (sort of lingering memories, waiting room, heavenly alternative). A nice, short (4 min.) [[clip by Studiocanoe|https://vimeo.com/144047596]] animates one Eagleman story (transcript below). ''Sum'' >In the afterlife you relive all your experiences, but this time with the events reshuffied into a new order: all the moments that share a quality are grouped together. > >You spend two months driving the street in front of your house, seven months having sex. You sleep for thirty years without opening your eyes. For five months straight you flip through magazines while sitting on a toilet. > >You take all your pain at once, all twenty-seven intense hours of it. Bones break, cars crash, skin is cut, babies are born. Once you make it through, it's agony-free for the rest of your afterlife. > >But that doesn't mean it's always pleasant. You spend six days clipping your nails. Fifteen months looking for lost items. Eighteen months waiting in line. Two years of boredom: staring out a bus window, sitting in an airport terminal. One year reading books. Your eyes hurt, and you itch, because you can't take a shower until it's your time to take your marathon two-hundred-day shower. Two weeks wondering what happens when you die. >One minute realizing your body is falling. Seventy-seven hours of confusion. One hour realizing you've forgotten someone's name. Three weeks realizing you are wrong. >Two days lying. Six weeks waiting for a green light. Seven hours vomiting. > >Fourteen minutes experiencing pure joy. > >Three months doing laundry. Fifteen hours writing your signature. Two days tying shoelaces. Sixty-seven days of heartbreak. Five weeks driving lost. Three days calculating restaurant tips. Fifty-one days deciding what to wear. Nine days pretending you know what is being talked about. >Two weeks counting money. Eighteen days staring into the refrigerator. Thirty-four days longing. Six months watching commercials. Four weeks sitting in thought, wondering if there is something better you could be doing with your time. Three years swallowing food. Five days working buttons and zippers. > >Four minutes wondering what your life would be like if you reshuffled the order of events. >In this part of the afterlife, you imagine something analogous to your Earthly life, and the thought is blissful: a life where episodes are split into tiny swallowable pieces, where moments do not endure, where one experiences the joy of jumping from one event to the next like a child hopping from spot to spot on the burning sand. !!!!Here is a brief description of some other short stories in his book: ''Descent of Species'' - after you die, you can choose to live as anything or anyone you like, e.g. like a horse leading a simple, enjoyable life in a pasture (__but__, with no way up the irreversible descent, since as a horse you don't have a clue, when __you__ die, what are some other options for "the next round".) :: - reminds me of the [[missed opportunity described by Terry Pratchett.|Wisdom and questions (or questioning wisdom; or 'careful what you are asking for')]] ''Spirals'' - meeting our Creator(s) which turn out to be somewhat dim-witted. They created us as their machines to try to figure out the Big Questions of Life. But we became too advanced for them to understand what we are saying, and that we're looking for the answers to the same questions. Are we on the same trajectory with the machines we are building? ''Death Switch'' - personal software which starts as an auto-reply email announcing our death (and revealing things like passwords and bank account numbers to our heirs), but evolving into its own entity representing the individual, exchanging experiences with other entities, where the entire human race slowly dies off and leaves behind a virtual culture of virtuals (basically kwetching like in an elderly home (or in Heaven...)
In a blog post titled [[Summary of the Prisoner’s Dilemma|http://reasonandmeaning.com/2015/05/02/game-theory-and-the-prisoners-dilemma-in-two-pages/]] by [[John G. Messerly|http://reasonandmeaning.com/brief-bio/]] he writes: >The prisoner’s dilemma is one of the most widely debated situations in game theory. The story has implications for a variety of human interactive situations. A prisoner’s dilemma is an interactive situation in which //it is better for all to cooperate rather than for no one to do so, yet it is best for each not to cooperate, regardless of what the others do//. Messerly summarizes the classic scenario/story: >In the classic story, two prisoners have committed a serious crime but all of the evidence necessary to convict them is not admissible in court. Both prisoners are held separately and are unable to communicate. The prisoners are called separately by the authorities and each offered the same pro-position. Confess and if your partner does not, you will be convicted of a lesser crime and serve one year in jail while the unrepentant prisoner will be convicted of a more serious crime and serve ten years. If you do not confess and your partner does, then it is you who will be convicted of the more serious crime and your partner of the lesser crime. Should neither of you confess the penalty will be two years for each of you, but should both of you confess the penalty will be five years. In the following matrix, you are the row chooser and your partner the column chooser. The first number in each parenthesis represents the “payoff” for you in years in prison, the second number your partner’s years. Let us assume each player prefers the least number of years in prison possible. >So you reason as follows: If your partner confesses, you had better confess because if you don’t you will get 10 years rather than 5. If your partner doesn’t confess, again you should confess because you will only get 1 year rather than 2 for not confessing. So no matter what your partner does, you ought to confess. The reasoning is the same for your partner. The problem is that when both confess the outcome is worse for both than if neither confessed. You both could have done better, and neither of you worse, if you had not confessed! You might have made an agreement not to confess but this would not solve the problem. The reason is this: although agreeing not to confess is rational, compliance is surely not rational! and concludes: >The prisoner’s dilemma describes the situation that humans found themselves in in Hobbes’ state of nature. If the prisoners cooperate, they both do better; if they do not cooperate, they both do worse. But both have a good reason not to cooperate; they are not sure the other will! We can only escape this dilemma, Hobbes maintained, by installing a coercive power that makes us comply with our agreements (contracts). Others, like the contemporary philosopher David Gauthier, argue for the rationality of voluntary non-coerced cooperation and compliance with agreements given the costs to each of us of enforcement agencies. Gauthier advocates that we accept “morals by agreement.” [[Modeling and simulating various scenarios of the Prisoner's Dilemma|Prospects of Modeling]] can provide useful insights into aspects such as human nature, collaboration vs. competition, morality, mechanisms of government, and more. [[Messerly also nicely analyzes ethical behavior|On ethical behavior]] in light of the Prisoner's Dilemma.
In his book When Things Start to Think (see [[chapters online|http://www.kurzweilai.net/neil-gershenfeld]]), Neil Gershenfeld talks about some of the best practices they have at the Media Lab at MIT to support learning and human performance. On the motivation for getting into Human Performance Support: >If we look around us now, the single most common reaction to computers was entirely missed by any of the historical visions: irritation. Computers taking over the world is not a pressing concern for most people. They re more worried about figuring out where the file they were editing has gone to, why their computer won t turn on, when a Web page will load, whether the battery will run out before they finish working, what number to call to find a live person to talk to for tech support. >The irritation can be more than petty. A 1997 wire story reported: >>ISSAQUAH, Wash. (AP) A 43-year-old man was coaxed out of his home by police after he pulled a gun on his personal computer and shot it several times, apparently in frustration. >Apparently? He shot it four times through the hard disk, once through the monitor. He was taken away for mental evaluation; they should have instead checked the computer for irrational and antisocial behavior. On augmenting physical reality and blending into it, creating a "smarter environment" (or is it a "smarter performer"?) >Instead of struggling to create a computer world that can replace our physical world, there's an alternative: augment it. Embrace the means of interaction that we ve spent eons perfecting as a species, and enhance them with digital content. >You can think of this as a kind of digital shadow. Right now objects live either in the physical world or as icons on a computer screen. User interface designers still debate whether icons that appear to be three-dimensional are better than ones that look two-dimensional. Instead, the icons can really become three-dimensional; physical objects can have logical behavior associated with them. >A business card should contain an address, but also summon a Web page if placed near a Web browser. A pen should write in normal ink, but also remember what it writes so that the information can be recalled later in a computer, and it should serve as a stylus to control that computer. A house key can also serve as a cryptographic key. >Each of these things has a useful physical function as well as a digital one. >Taken together, ambient displays, tagged objects, and remote sensing of people have a simple interpretation: the computer as a distinguishable object disappears. Instead of a fixed display, keyboard, and mouse, the things around us become the means we use to interact with electronic information as well as the physical world. Today's battles between competing computer operating systems and hardware platforms will literally vanish into the woodwork as the diversity of the physical world makes control of the desktop less relevant. >A window is actually an apt metaphor for how we use computers now. It is a barrier between what is inside and what is outside. While that can be useful at times (such as keeping bugs where they belong), it's confining to stay behind it. Windows also open to let fresh air in and let people out. >All along the coming interface paradigm has been apparent. The mistake was to assume that a computer interface happens between a person sitting at a desk and a computer sitting on the desk. We didn't just miss the forest for the trees, we missed the earth and the sky and everything else. The world is the next interface. >In retrospect it looks like the rapid growth of the World Wide Web may have been just the trigger charge that is now setting off the real explosion, as things start to use the Net so that people don't need to. As information technology grows out of its awkward adolescence, bringing more capabilities closer to people is proving to be the path to make it less obtrusive and more useful. (ch. 14 - Things That Think)
From [[Discover Magazine|https://www.discovermagazine.com/the-sciences/infinity-plus-one-and-other-surreal-numbers]] by Polly Shulman (November 30, 1995). John Conway discovered them; Donald Knuth wrote a novelette about them, Martin Kruskal studied them for decades, and here is a simple example, which embodies the suggestion by Margaret Mead: > If one cannot state a matter clearly enough so that even an intelligent twelve-year-old can understand it, one should remain within the cloistered walls of the university and laboratory until one gets a better grasp of one’s subject matter. How do the surreals work? Imagine, as posture specialists like to suggest, that there’s a string attached to the top of your head, and you’re dangling from it. Feel those vertebrae line up in a nice, straight row? Now imagine that your spine, instead of stopping at your skull and your coccyx, goes on forever along that string, extending above your head past the farthest star and below your feet through the Earth and beyond, never stopping. Got that? Good. Now imagine that there’s one small problem: somewhere along your spine, you have an itch you can’t reach. I’ll scratch your back if you scratch mine, offers a friendly alien, positioning its fingernail on the vertebra between your shoulder blades. Just tell me where. Up, you say. The alien moves up a vertebra, but it hasn’t yet reached the itch. Up, up, up, up, up, you repeat, and each up inches the alien fingernail one vertebra higher. After 40 or so ups, you sense the alien is getting close, but at the forty-fourth vertebra, you know it’s gone too far. The itch is between vertebra 43 and vertebra 44. Down, you say. The alien moves its fingernail down half a notch, to the point midway between vertebra 43 and vertebra 44. Unfortunately, it’s gone past the itch again. Up, you direct it. It goes up a quarter of a notch this time, to the midpoint between its former spot and vertebra 44, reaching the place three-quarters of the way between vertebra 43 and vertebra 44. Right there, you say, and the alien scratches. Ah! The spot the alien just scratched is designated by the directions you gave the alien--44 ups, followed by 1 down and 1 up. The sequence that replaces each up with a down and vice versa--that is, 44 downs followed by 1 up and 1 down--would take the alien’s fingernail to the spot 43¾ vertebrae below the place between your shoulder blades where it started. The sequence of no ups or downs would tell the alien to scratch that original spot. Up, down, down, up, down, up would take the alien’s nail to the spot 11/32 of the way between the original spot between the shoulder blades and the first vertebra. Which itches will you be able to direct the alien to in a finite amount of time (that is, by saying up and down a finite number of times)? Whenever you say up or down, the alien moves its fingernail one vertebra, or half the distance between two vertebrae, or a quarter of the distance, or an eighth of the distance, or a sixteenth of the distance, and so on. So the finitely scratchable itches will be the ones that occur at the integers or at the dyadic fractions--fractions with a power of 2 in the denominator. Now suppose you have an itch two-thirds of the way between vertebrae 2 and 3. Up, up, up, you say. That takes you to vertebra 3. Down, you add. That takes you to 2½, which is not far enough. Another up takes you to 2¾--too far. Another down takes you to 2⅝, too low again. Up down, up down, up down, you say, each time getting closer but never quite achieving that two-thirds mark. To reach it, you’ll have to repeat up down, up down, up down forever. At the end of eternity, after infinitely many up downs, the alien’s fingernail scratches the spot on your back two-thirds of a vertebra past vertebra 2. Ah! If your spine is a number line, the itchy spots on your back are numbers, and since each set of directions you give the alien--those strings of ups and downs--designates one and only one itchy spot, you can think of the directions as numbers, too. These are the surreal numbers: numbers that can be designated by a string of ups and downs some ordinal number in length. Every integer is a rational number and every rational number is a real number, and in the same way, every real number is also a surreal number. However, there are many, many remarkable surreal numbers that aren’t real. Just as you can write rational numbers as infinitely repeating decimals, you can designate any nondyadic, rationally placed itch by directing the alien with a unique, infinitely repeating string of ups and downs. (And just as you can write irrational real numbers as infinitely long, nonrepeating decimals, you can designate real, irrational itches by using infinitely long, nonrepeating strings of ups and downs.) But not all infinitely repeating strings of ups and downs designate rational numbers. Suppose, for example, you have an itch way, way up at the end of your infinitely long spine. Up, you tell the alien. Up, up, up, up, up. You go on repeating up forever, and when forever is over, the alien scratches. That spot is called omega (and designated by the Greek letter w), just like Cantor’s ordinal that describes the collection of all positive integers. It’s not a rational number or a real number; it’s too big. Omega is the simplest surreal number larger than all real numbers. Now suppose you have an itch the barest smidgen above zero. (Think of zero as the shoulder-blade spot where the alien’s fingernail starts out.) Up, you say. The nail moves to vertebra 1, which is way too far. Down, you say, down, down, down. You go on saying down, and each time, the alien moves its nail closer to zero, but it doesn’t quite reach the itch. You go on repeating down forever. When forever is over, the alien scratches a spot that’s above zero but beneath every positive real number. Kruskal calls that spot iota (ι); it’s the simplest infinitesimal surreal, the simplest number larger than zero but less than all the positive reals. Two ups followed by infinitely many (that is, omega) downs will tell the alien to scratch you on the spot iota above your first vertebra. One down followed by omega ups will get you a scratch iota below the zero spot. Up, up, down, up followed by omega downs will get you a scratch iota above 1½. And so on. [Martin] Kruskal writes these strings of ups and downs using arrows pointing up and down; for example, he’d write the number ¾, up down up, like so: ↑↓↑. When a particular segment of ups and downs is repeated omega times, he puts a round cap over it, so omega would be ↑(cap), ⅓ would be ↑↓↑(cap)↓(cap), and minus iota would be ↓↑(cap). Now it’s the alien’s turn to have an itchy spine. It reminds you of your half of the bargain. The alien’s anatomy is rather more complex than yours, though. For one thing, it has infinitely many infinitely long spines. Up, up, up, it tells you forever, and when forever is over, you arrive at the alien’s first omega spot, ↑(cap). You’re all ready to scratch, but the alien stops you. No, not quite there. Up another vertebra. To get to the omega spot, you had to go past all the vertebrae on the alien’s first spine, so those instructions take you to its next one. (In fact, it’s useful to think of the first spine’s omega spot as the zero spot on the second spine.) The itchy place the alien specified, ↑(cap)↑, is the first positive vertebra on that new spine. Now suppose that once you arrived at omega, the alien had said down instead; that spot would be the first negative vertebra on the second spine. If the alien told you omega ups, followed by another omega ups, followed by an extra up, ↑(cap)↑(cap)↑, you’d reach the first positive vertebra on the third spine. Just as one up followed by one down gives you ½, omega ups followed by omega downs, ↑(cap↓(cap), gives you half omega. And omega ups, followed by omega ups, followed by omega ups, and so on omega times--written ↑(cap)↑(cap)↑(cap)...=↑(2cap)--will send your fingernail past all the vertebrae on all omega spines of the alien’s back. Now what? What happens when you’ve gone beyond all omega spines? Well, did I mention that the alien has infinitely many backs? Omega of them, to be precise. To send you to a spot, say, one-third of the way between the second and third vertebrae on the negative fifth spine on the eighth back, the alien has but to tell you ↑(2cap)↑(2cap)↑(2cap)↑(2cap)↑(2cap)↑(2cap)↑(2cap)↓(cap)↓(cap)↓(cap)↓(cap)↑↑↑↓(↓↑). Oh, and by the way, the alien has omega bodies with omega backs on each. Actually, it consists of omega populations of omega bodies, each with omega backs. Also, there are omega collections of omega populations of--well, you get the idea. There’s no end to the alien’s itchy back. As you can tell by picturing that back, the surreals have a somewhat involved structure. For one thing, unlike the real number line, which has no holes in it, the surreal number line is riddled with gaps. There’s a gaping hole between the finite numbers and the positive infinites, for example. (That particular hole is what people often mean when they talk about infinity.) There’s another gap between the infinitesimals and the positive real numbers. There’s another that separates zero from every positive number. (That one’s not quite a gap; I call it a cut, says Kruskal. It acts a lot like zero, but it isn’t really a number.) These gaps and cuts can be represented by arrow sequences of length greater than any ordinal number, and they’re everywhere. You can find one between any pair of numbers. +++ For the surreal numbers to be more use than, say, the ordinals, we have to be able to perform arithmetic with them. That means defining familiar operations--such as addition, subtraction, multiplication, division, exponentiation, logarithms, and so on--so that they work as well for surreal numbers as they do for the usual reals. A concept that Kruskal calls earliness is what makes such definitions possible. Take a surreal number and chop it off after a certain number of ups and downs. Throw out the ups and downs that come after the spot where you chopped. The number you’re left with is called a truncate of the first number. It may have an infinite number of arrows, of course: for example, ↑(cap) is a truncate of ↑(cap)↑↑↑. One surreal number is said to be earlier than another if it’s a truncate of the other. Earlier doesn’t necessarily mean smaller. One number is defined as smaller than another if they’re not equal, and at the first place where they differ, it either stops or has a down where the other either stops or has an up. As you can see if you think about the alien’s back, ↑↑ is earlier than ↑↑↓↓↓, but bigger. And given a pair of numbers, it needn’t be the case that one is earlier than the other--think of ↑↓↓↑(cap) and ↑↓↑↓. So the surreal numbers aren’t totally ordered under earliness, they’re only partially ordered. However, it’s easy to see that if one number is earlier than another, its arrow sequence will be shorter. The earliest number is the empty sequence, zero. You could get zero by chopping off any number before it started. The two next earliest are up and down--namely 1 and -1--since every arrow sequence starts with either up or down. Then come up up, up down, down up, and down down--that is, 2, ½, -½, and -2. And so on. Earliness provides the surreal numbers with an order that’s independent of size. The earliness ordering has another important quality: every nonempty class of numbers has at least one earliest number (remember, not all numbers in a class can be compared for earliness--two or more numbers could be the earliest in the class). This property makes it possible for mathematicians to use the earliness ordering to find definitions and proofs and carry out other vital mathematical activities, relying on a method called transfinite induction. The principle of induction says: If whenever a statement is true for every number earlier than x it’s also true for x, then it’s true for all the surreal numbers. Conway, Kruskal, and their colleagues used induction to define all the important operations from addition on up, and even one from calculus--differentiation. For ordinary, real numbers, these definitions give exactly the same results as conventional definitions, but, as Kruskal points out, they’re far, far simpler. And as a bonus, they also make sense for the new, wacky surreals, like omega and iota. The definitions allow surrealists to ask questions like: Which surreal numbers can be considered analogous to the integers? Which, if any, are prime? Which are rational--that is, which can be written as the quotient of two surreal integers? That last question has a surprising answer. Conway and Kruskal each came up with a reasonable definition for surreal integers, definitions that turn out to be equivalent, and by those definitions, any real number times omega is a surreal integer. So every real number is rational in the surreal system, even the square root of 2--just write it as (√2ω)/ω. If only someone had told Pythagoras. It wasn’t until Kruskal and his colleagues tried to define integration, an operation from calculus that tells you how much area the graph of a function encloses, that they ran into trouble. Our definition works for real-valued functions but not for surreal ones, because of the gaps in the surreal number line, says Kruskal. I’m working to fix it, but I don’t see any easy way to do so. Martin’s project, if it succeeds, would be absolutely fabulous, says Conway. This will allow him to find exact solutions to equations that so far have had only approximate solutions. Even without a working definition of integration, there’s a lot Kruskal can do with surreals. (You might need a bit of math beyond counting and scratching to understand his applications, so don’t worry too much about the details.) Since one of the main purposes of numbers is to measure quantities, for example, you’d expect a new bunch of numbers would allow you to measure things that never had a good yardstick before. Indeed, the surreal numbers turn out to be just the thing for evaluating how quickly functions grow. Recall from high school algebra that the graphs of certain functions head off to infinity when they reach a particular point on the x axis. But how soon do they get there? The surreal numbers, with their subtle varieties of infinite numbers, are a perfect tool for studying these asymptotic functions. Another trick mathematicians find immensely profitable is breaking down numbers or functions into simpler components. By writing a quantity that’s difficult to get a handle on as a sum of smaller and smaller terms, you can get closer and closer approximations to the difficult quantity. When he began working on surreal numbers, Conway made a stab at describing their anatomy; later Kruskal came up with a powerful, intricate, and precise way to dissect them, based on certain surreal numbers that can’t be broken down any further. These numbers, which he calls travagances, come in two kinds: extravagances and intravagances. An extravagance is a positive number that can’t be arrived at by performing finitely many algebraic, logarithmic, or exponential operations on earlier numbers. The earliest extravagance is omega: no amount of multiplying a finite number of finite numbers together, however big they are, or raising finite numbers to finite powers over and over again a finite number of times, or anything like that will get you to omega. And of course, there are lots--and lots and lots--of others beyond omega. If an extravagance is an enormously large (or small) number, an intravagance can be thought of as an enormously medium number, one very, very, very deeply embedded between two other numbers. Kruskal uses travagances to study what he calls nice functions, functions of the sort that you can describe using a familiar-looking formula consisting of plain old operations. What happens to these functions when they hit surreal numbers? What about when they run into gaps in the surreal number line? Since one such gap is infinity, this is a fairly significant question. People are always trying to figure out exactly what various functions do when they cross infinity. To find answers, Kruskal plugs in a carefully chosen extravagance, which he calls a ghost. A ghost stands in for a gap in the surreal number line, but since it’s actually a number, you can manipulate it as you would any other number.
In an [[interesting (and short) interview/Q&A with Sanjoy Mahajan|http://mitpress.mit.edu/blog/pi-day-q]] author of [[Street-Fighting Mathematics|http://mitpress.mit.edu/sites/default/files/titles/content/9780262514293_Creative_Commons_Edition.pdf]], in honor of 2013 Pi Day, Sanjoy brought up a few key points about learning and teaching math. (here's a [[local copy|resources/pi-day-q.html]] of the full Q&A) * In response to the question ''Has the proliferation of technology affected our ability to think for ourselves?'' (in the context of technology that can do math for us such as cell phones, tablets, computers, and calculators) ** Sanjoy responded that "Knowing that a computer can do a calculation, and even knowing how to ask a computer to solve a problem, is psychologically very different from being able to solve the problem oneself, even or especially approximately." *** which brings up an interesting psychological aspect, not frequently raised, namely the sense of mastery and control over our environment, knowledge, learning path, etc. It's a "twist" on Sir Francis Bacon's saying that "knowledge is power". As [[I had said elsewhere|http://ldtprojects.stanford.edu/~hmark/index_stanford.html]], I think that he is certainly right, //but//, with the explosion of data (and knowledge), ''access to knowledge'' is also an important part of the power (to be learned and mastered). But the point Sanjoy is making is that if you become so dependent on the search/access and lose intuition/knowledge as to is it true, does it make sense (critical, analytical thinking skills), then you (and your knowledge and skills) are on very shaky grounds. * On a question about how math should be taught (compared to how it is taught), Sanjoy responded: >Mathematics is a way of expressing relationships in the world: It is a language. And we learn languages best through speaking meaningful sentences, long before we master all the grammar points in the sentence. >Thus, students have to use mathematics to model and draw conclusions about the world, rather than memorizing procedures, such as long division, best left to the pocket calculators. As an example, teach calculus through physics. Physics is why and how calculus was invented: to understand the motions in the heavens -- not to compute the rate at which the water level rises when filling an upside down cone. ** which is similar to points others like [[Lockheart|resources/LockhartsLament.pdf]], [[diSessa|resources/diSessa%20-%20Changing%20Minds%20-%20Chapter1.pdf]], and [[Polya|https://archive.org/download/Induction_And_Analogy_In_Mathematics_1_/Induction_And_Analogy_In_Mathematics_1_.pdf]] are making, regarding math as a language, and the way to master math by doing it in a way real mathematicians are doing it. ** and this is [[the point the mathematician Edward Frenkel makes as well|Edward Frenkel on teaching math]]. * On the question: What do you mean by "too much mathematical rigor teaches rigor mortis"?, Sanjoy has this to say: >Mathematics, especially in the last 150 years, has focused ever more on never making a mistake. Perhaps the Weierstrass function started the downhill slide. Discovered in 1872, it is a function continuous everywhere (has no jumps anywhere) yet differentiable nowhere (is spiky everywhere). Its discovery contradicted the intuitions about calculus and functions upon which mathematicians and physicists had depended. The worry was that it was not the only counterexample. And mathematics became ever more worried about not getting caught by a counterexample. Unfortunately, the surest way to never make a mistake is to never do anything. The fear of mistakes is a recipe for paralysis -- for [[rigor mortis|Formalism First = Rigor Mortis. Intuition First = Rigor's Mortise]]. * which is similar to the point I was making about the need to [[loosen up a bit|A case for "loosening up a bit"]], very funnily (and pointedly) depicted by [[Ursus Wehrli|http://www.kunstaufraeumen.ch/en]]. I think that this is one case where mathematicians can learn from scientists about "one case/example (Weierstrass) may not be a cause to "push the abort button" on an entire way of thinking/doing/teaching. Even though, these kinds of exceptions/findings are usually (and justifiably, in most cases) a "death knell" to mathematical proofs.
This semester, in the first week of teaching "Exploring Computer Science" in High School (using Scratch from MIT), we were learning to program the sprites to draw different shapes on the screen. I showed the students how to draw the [[first few generations of the Koch Curve|http://fractalfoundation.org/resources/fractivities/koch-curve/]], and as a motivator and demonstration of the "self-similarity" of fractals in general, and this fractal in particular, I showed them an animation of [[diving into an "endless" Koch Snowflake|https://www.youtube.com/watch?v=PKbwrzkupaU]]: <html><iframe width="560" height="315" src="https://www.youtube.com/embed/PKbwrzkupaU" frameborder="0" allowfullscreen></iframe></html> (and another, more "mind-blowing" [[dive-in/odyssey into another famous fractal - The Mandelbrot Fractal|https://www.youtube.com/watch?v=PD2XgQOyCCk]]) <html><iframe width="560" height="315" src="https://www.youtube.com/embed/PD2XgQOyCCk" frameborder="0" allowfullscreen></iframe></html> The students got the idea of self-similarity, and did draw 3-4 generations of the Koch Curve, but without recursion (which we had not learned yet, since it was the first week of an introductory CS class), drawing more generations gets pretty tedious. Again, as a motivator and a "sight of things to come" I showed them a recursive implementation in Scratch, and was pleasantly surprised by the gasps and groans of some of the students pleading to teach them variables and recursion. <html><iframe allowtransparency="true" width="485" height="402" src="http://scratch.mit.edu/projects/embed/95251322/?autostart=false" frameborder="0" allowfullscreen></iframe></html> And I found myself wondering: when was the last time a group of students //pleaded// a teacher to teach them some advanced math concepts like variables and recursion? Isn't Computer Science full of potential? :) Albert Einstein summarized it well: >"Teaching should be such that what is offered is perceived as a valuable gift and not as a hard duty."
I'll start with "an aside", to get it out of the way (pun intended ;-) :
I stumbled across [[the website of the game designer Jonathan Blow|http://number-none.com/blow/]] (of //Braid// and //The Witness// games fame), as I was searching for insights into motivation and engagement in the context of learning/education, which in good games are no problem, but seem to be a big obstacle in studying/school.
What caught my eye on Blow's site was a link to a short (13MB, 4 minutes) [[Tai Chi video clip|http://www.youtube.com/watch?v=TBvF6r6DOvc]], that according to him "rocks his socks". He is right; it's a delight to watch!
Blow also refers to another game designer, [[Raph Koster|http://www.raphkoster.com/]], who [[I also wrote about|Theory of fun - Raph Koster]].
Another link that caught my attention was to another game designer, Brian Moriatry (of //Loom// and //Beyond Zork// game fame), and from [[Moriatry's website|http://ludix.com/moriarty/index.html]], a description of a [[game design programming language he calls Perlenspiel|http://www.perlenspiel.org/]], after Herman Hesses's book [[The Glass Bead Game (German: Das Glasperlenspiel)|http://en.wikipedia.org/wiki/The_Glass_Bead_Game]]. In an [[insightful article about some design considerations|http://ludix.com/moriarty/lehr.html]] for the Perlenspiel language, Moriarty has this nerdy/programmer textual-visual pun:
<a href="resources/setter-getter-small.png"><img src="resources/setter-getter.png"></a>
This setter is also a getter^^1^^
!!!!Now that the aside(s) is(are) out of the way, here are some of my observations on Moriatry's game design and Perlenspiel language
* I can totally relate to and sympathize with Moriatry's observation that he was looking for a language/environment/engine
>...so transparent that students could sit down and start doing useful work after just a few evenings of study, fingering out ideas like notes on a piano.
>What I wanted was a gameclavier.
>Alas. There are no Steinways or Bosendorfers in this business.
>If I wanted a gameclavier, I was going to have to build it myself.
** I definitely feel and [[wrote about a similar need|Universal Emulator]] for an educational simulation/emulation language/environment/engine
* It's interesting and revealing (in the sense of "pointing to a direction") that there are similar themes^^2^^ (at least from my cursory initial review and understanding) between [[Perlenspiel|http://www.perlenspiel.org/]] and [[NetLogo|http://ccl.northwestern.edu/netlogo/]]. For example:
** The simple 2D grid of "beads" (Perlenspiel) vs. "patches" (~NetLogo)
** A relatively easy to learn/use but powerful scripting/programming language: Javascript (Perlenspiel) vs. Logo (~NetLogo)
** The web-enabled access. Even though
*** I haven't tried Perlenspiel's environment yet, and
*** ~NetLogo has the ability to save and __execute__ programs (games) as Java applets, which is not ideal, but good enough in terms of openness and ubiquity. ~NetLogo __programming__ is __not__ web-enabled!
** The "low threshold, high ceiling" design mentality of both, enabling users to create "personally meaningful experiences" relatively quickly -- a powerfully motivational approach to learning and performance
* Creating "personally meaningful experiences" is a concept that Constructionists like Papert and Resnick are using, and it drives powerful and deep learning. In [ext[the article|resources/Moriatry-Perlenspiel.html]], Moriarty outlines the flow of a seven week course in game design, which while simple, would be very effective, in my opinion.
** ''class 1'' - basic definitions for play, toy, game and puzzle^^3^^; brief summary of how the Perlenspiel engine works; URL to the Perlenspiel website; URLs of ebooks and Web sites describing Javascript; no programming instruction; no solved and showcase examples. ''Homework'': build __a toy__ in Perlenspiel.
** ''class 2'' - reviewing and discussing the toys that everyone had built in Perlenspiel; pair assignment to prototype __a puzzle__ with Perlenspiel.
** ''class 3'' - a playtesting studio for the puzzle in Perlenspiel. ''Homework'': use the feedback to complete and polish their puzzles.
** ''class 4'' - critiquing the completed puzzles.
** ''class 5 and beyond'' - game projects, 2 sessions per game, where the first session was devoted to playtesting, the second to presenting and critiquing.
In the last part of his article Moriatry is sharing some interesting insights as a teacher, after he himself finished coding a game in his own (Perlenspiel) environment:
>Nearly three weeks later, the game was sort-of finished.
>I had forgotten how difficult it is it write for bare pixels without sprites, or z-planes, or scrolling, or an animation system, or any of the conveniences we ve all come to take for granted.
>For the first time, I realized just how much I had been asking when I told my students to write six games in seven weeks, and what they had gone through to satisfy me.
>Perlenspiel demonstrated to this old Professor how hard students will work if they are playfully and firmly challenged.
----
^^1^^ referring to Object Oriented (OO) methods ("function calls" in non-OO parlance) for setting variable values and retrieving (getting) them
^^2^^ Themes in a sense similar to what Mark Twain^^3^^ said about history: history does not repeat itself, but it does rhyme
^^3^^I was serendipitously surprised and delighted to see Moriatry's reference to Twain in the article:
>some basic definitions for play, toy, game and puzzle ... inspired by The Adventures of Tom Sawyer, in which Mark Twain memorably remarks that Work is whatever a body is obliged to do, and play is whatever a body is not obliged to do.
>** Play is superfluous action.
>** A toy is something that elicits play.
>** A game is a toy with rules and a goal.
>** A puzzle is a game with a solution.
Here are some things that I found working in my CS classes. (In many cases, I had stumbled upon them, and got confirmation/validation/encouragement later ... :( * Giving students "gift code" - Working with students 1:1 for a few minutes at a time, or as needed, asking them what they want to do, and giving them some concrete ideas (blocks in Scratch work well :) to get going. In a few minutes they get an important nugget of knowledge, a concept, a trick, etc. and totally "own it" in the context of their interests and creations - [[CSTA blog on Gift Code|http://blog.csta.acm.org/2015/02/03/teaching-and-learning-with-gift-code/]] * One of the [["Big Ideas" in CS|The Big Ideas and Computational Practices of Computer Science*]] is that "Computing is a creative human activity". I deeply believe in it, and weave/embed opportunities for creativity throughout the curricula I have designed (i.e., a unit on creativity is as ludicrous as the demand to "act spontaneously now!"). ** Here are some tips I have been following (and later discovered at the [[CSTA blog|http://blog.csta.acm.org/2015/09/08/cs-principles-and-creativity/]]) that I found very common-sensical: *** Let students know that there are usually multiple paths that lead to understanding. *** Arrange student collaborations which provide meaningful (to them) real-world, problem-solving opportunities. *** Provide lots of project and performance choices which employ a variety of “intelligences” whenever feasible. *** Encourage them to look for and experiment with new things and ideas. *** Encourage questioning. (since, [[questions are like lanterns|John O’Donohue - questions]]) *** Be sure your grading does not penalize “less than successful” creativity. Students will not feel free to experiment if their grade hinges on some abstract measure of success. The true reward for being creative is purely intrinsic. *** Encourage them to view mistakes as opportunities for learning rather than failures. *** Enable students to exchange, value, and build upon the ideas of others. Share interesting examples of technological creativity that you run across in the media. *** Make time for informal interactions between students. *** Offer a safe environment which encourages risk-taking. Avoid a competitive and extrinsically rewarding classroom, by providing a friendly, secure, and comfortable environment. * How to encourage girls to do more Computing/CS (from the [[CSTA Blog|http://blog.csta.acm.org/2015/10/20/disrupting-the-gender-gap-in-computer-science/]]): ** Generally, it's about the message you send to the female students through the way the classroom looks, the assignments given, and the way they are asked to complete them: *** Keep the classroom decor neutral. Or maybe add some posters of women in Computer Science to go alongside your Mark Zuckerberg and Bill Gates posters. Think Grace Hopper, Jean Bartik, Maria Klawe, Karli Kloss, or Marissa Mayer. Recent research shows that when the classroom is neutral, girls are three times more likely to show an interest in Computer Science than when the CS classroom is stereotypically geeky. It makes a difference. *** Think about your assignments. Are they the same assignments you did in high school? Unless you were in high school a few years ago, it might be time to update them. Connect your assignments to the real world. Many girls particularly like to see practical applications of the work they’re doing in class. Girls, in particular, also like to know that the work they’re doing could potentially help someone or help solve a problem that plagues the world. *** Also think about how you have your students work on assignments. Does everyone complete all the assignments individually? Consider using pair programming, peer instruction, and group work. All of these methods not only make the work potentially more appealing to girls, who appreciate the social aspects of work, but they also help all students retain Computer Science concepts. They’re very effective pedagogical strategies. *** Finally, encourage your students, especially your female students, along the way. When they make a mistake in class, be supportive, help them learn from it. If a girl seems to like CS, whether or not she’s good at it, encourage her to take another course or enroll in a summer program, or pursue CS at the next level, whether that’s high school, college or graduate school. [[Recent research from Google|https://docs.google.com/file/d/0B-E2rcvhnlQ_a1Q4VUxWQ2dtTHM/edit?pli=1]] shows that encouragement is a key factor in retaining women to continue their student of CS.
Here are a few instances where I could actually see "the teaching spark lighting the learning fire" when teaching Science, Technology, Engineering, and Math (STEM) courses:
!!!Amazing Mazes - multiple representations
* In a course titled "Amazing Mazes", I taught middle school students how to build mazes in a 2D plane and then program "maze walkers" (think, "mice") to run through their mazes. In the course segment about different representations, we learned that the maze can have (at least) two different representations, each one useful for different reasons and purposes: the one is the visual representation, showing the maze paths graphically; the other is the "programmatic representation", showing the commands for creating the same maze.
[img[Maze representations|resources/maze-representations.png][resources/maze-representations.png]]
* All students understood the purpose of the "Visual Representation" and used it to plan their maze walks and walker programs. The usefulness of the "Program Representation" became obvious only when we learned how to manipulate this representation to create more complex mazes, using translation, reflection, and scaling.
* As it turns out, one 7th grade girl in class got an important piece of the connection and usefulness of the two forms of representing a maze. Instead of just copying and pasting the commands and parameters from the history box into the command input, and running them (to display the original maze), she added 10 (I guess she correctly reasoned that it'd be easier) to each command parameter (coordinate in the x-y plane), and then ran the commands. I don't know who was more pleased with the resulting translated (shifted) shape on the screen, I, because I was able to teach, or she, because she was able to learn!
!!!Right on Target - predicting with reflection/symmetry
*In a course titled "Right on Target", I taught middle school students about ballistic missiles through a game teaching them how to hit targets with their missiles. The students played with simulations enabling them to explore various parameters like missile speed and angle, target distance and height, and gravity constant (for example, on earth and on the moon).
* The simulation speed was realistic, so it took a while for the students to see their missile fly and hit or miss the target, and they became a bit impatient. This was a good thing! Some students were starting to figure out ahead of time whether the missile will hit the target this time (guessing leading to prediction!)
[img[Right on Target competition|resources/ejs_trajectories_moon_45_small.png][resources/ejs_right_on_target.png]]
* It turns out that the students became pretty good at estimating hits/misses, and in the process discovered the symmetry of the arc (parabola) the missile was following. This made it easier later on to explore and explain the two possible ways to hit a target, with two different launch angles (since the parabola/path is quadratic, meaning it has two roots/solutions):
[img[Right on Target competition|resources/ejs-balistic-trajectory-1.png][resources/ejs-balistic-trajectory-1.png]]
!!!Simplexity (simple rules leading to complex behaviors) - modeling for prediction
* In a course titled "Simplexity", I taught middle school students how simple rules, when continuously applied, can lead to complex ("unpredictable") behaviors. As an example, we analyzed Conway's Game of Life (which has 4 rules), starting with some simple initial conditions ("colonies"), and went through some fairly complex evolutions.
* After a few simulation runs, where students marveled the movements on the screen, one student got a great insight and exclaimed: This looks like the movement of clouds in the sky! We can use this to predict the weather! Another student excitedly added: no, no, this is like fires spreading in a forest! We could predict where it spreads and how to save trees and houses in the area.
|borderless|k
|[img[Forest Fires|./resources/Simplexity%20lesson%204%20screen.png][./resources/Simplexity%20lesson%204%20screen.png]]|[img[Game of Life 2 populations|./resources/GameOfLifeSideBySide-small.png][./resources/GameOfLifeSideBySide-small.png]]|
|borderless|k
!!!Meet Me on Mars (MMoM - creating an animation game, launching a rocket to Mars) - making connections^^1^^
In a course titled "Meet Me on Mars (MMoM)", I taught middle school students how to create a simplified model of our Solar System (astronomy), how to deal with mapping planet sizes, rotation periods, and distances correctly (math, engineering), and how to make a rocket launch from Earth, track Mars, and land safely (programming, engineering).
Towards the end of the course (lasting 10 weeks), and after proudly showing me a successful landing of her rocket on Mars, one of the students looked up at me and said: Mr. Mark, you know //so much//. I want to know as much as you do.
To which I responded: you definitely can, if you love what you do, //and// you are willing to work hard.
This probably reminded her of things we did in class and she said: You always ask hard questions.
I didn't know how to interpret this, so I asked her: hard in a good way, or hard in a bad way?
And she responded: hard-good.
and after a split second, she added: it makes me think of new things; it makes me want to know the answer.
Exactly!
Igniting the fire, for sure, but, maybe more in line with the course: Lift-off!
|borderless|k
|[img[Meet Me on Mars rocket launch|./resources/Rocket launch 4.png][./resources/Rocket launch 4.png]]|
|borderless|k
----
^^1^^ I brought up this example in a recent job interview for a CS/STEM teaching position, in response to a question "what would your students say about you?"
In his book //The Developer's Code// (in the good series the [[Pragmatic Bookshelf|https://pragprog.com/]]), Ka Wai Cheung makes a few good points about what to do if you are trying to teach a novice.
He makes the observation that "teaching is unlike programming", because:
* coding is not done linearly (or top to bottom, or from principles to details, etc.)
* when coding, programmers often "leave details" for later, and then come back to fill them in. This would potentially create big holes in understanding if teaching this way. For example, we compile our code to speed up error detection and correction ("let the compiler flag things" for us).
And he gives some suggestions:
* "Teach twice as slowly as you'd like to". Make all your "simple assumptions" and "obvious details" explicit and clear.
* Teach new concepts using obvious examples, concrete cases, and simple contexts. Avoid generalities, abstractions and theories, and make the examples as tangible and obvious as you can.
* "Lie to simplify". Pare down a complex topic and break it down to a "less than perfect" one, in the first iteration. Clear understanding of a concept, even if not 100% correct is motivating, and this will lead to a desire to know "the whole and correct" picture.
** or as the two great mathematicians Mark Kac and Stanislaw Ulam had said about teaching: Tell the truth, nothing but the truth, but not the whole truth^^1^^.
* Encourage independent thinking. Stuart and Hubert Dryfus called it "autonomous thinking": students start asking less technical questions and more strategic questions. They ask less about the "how and what" and more about the "why". This is a sign they thing there are better ways and what you taught them may limit their naturally developing intuition.
** encourage that, and ask them to come up with different/better solutions/approaches. Compare and contrast with less optimal solutions and dig as deep as they are willing to go. Differentiating is a great way to learn.
----
^^1^^ - see [[The importance of telling the whole truth]] :)
For me, the first challenge for computing science is to discover how to maintain order in a finite, but very large, discrete universe that is intricately intertwined. And a second, but not less important challenge is how to mould what you have achieved in solving the first problem, into a teachable discipline: it does not suffice to hone your own intellect (that will join you in your grave), you must teach others how to hone theirs. The more you concentrate on these two challenges, the clearer you will see that they are only two sides of the same coin: teaching yourself is discovering what is teachable.
In an [[interview of Sylvia Boorstein|https://soundcloud.com/onbeing/what-we-nurture-with-sylvia]] by Krista Tippett, Boorstein describes her experience when driving in her car, and how, whenever she makes a mistake, takes a wrong turn, or misses an exit, her GPS never gets mad or upset. It just says: recalculating, and then proceeds in instructing her on how to get back on track. So this is definitely an example of technology potentially "helping us to develop and cultivate spiritual practices", teaching us how to stay calm, not complicate things more than they already are, by becoming upset, or angry, or worried, or afraid. This is something we are encountering all the time: something happens, it challenges us, and we are figuratively at a fork in the road (ha!). We can either react negatively (or as Buddhists would say, in an "unwholesome way"), or make the wise choice and just "recalculate" :)
Can we, and should we learn from Nature, when it comes to implementing technology solutions? The argument can go both ways: On one hand nature is showing an astonishing variety, and incredible ingenuity in coming up with "solutions to problems", like locomotion (in the air, land, and water), adaptation to the environment, etc. (so much so, that some people are proposing/promoting an //Intelligent Design// as a "scientific alternative" to //Evolution and Natural Selection//. But this is a discussion for another time). On the other hand, many of the human solutions to the same/similar problems are different from the natural ones, or at least, different enough, to argue that we/humans cannot "just learn by copying" from nature. Some proverbial examples are: * Flight - where human airplanes use fixed wings, propellers, jets, etc. * Land-based transportation - mainly based on wheels, not on legs, slithering, etc. (not to mention things like magnetic levitation for high-speed trains, and other more "exotic" means) * Illumination - mostly based on electricity, not on fire, nor other chemical reactions So it is not so surprising that computer scientists working in the field of [[AI]] are, for the most part, not paying too much attention to how nature demonstrates intelligence. And I think that this is why people like Jeff Hawkins encountered such [[difficulties|01 - Artificial Intelligence]] when he tried to get into the AI Lab at MIT. I think that in his book //On Intelligence// he is making [[some very good arguments|characteristics of intelligent systems]] about why this approach (ignoring nature's ways of "implementing intelligence" - mainly in the evolution of the human neocortex) is a ''big mistake'', and the past and current ways of going about developing AI is misguided, and not fruitful.
From [[The Philosophers Mail|http://thephilosophersmail.com/wp-content/uploads/2014/04/Ten-Virtues.pdf]], (associated with the philosopher Alain de Botton), now "reincarnated" as [[The School of Life|http://www.theschooloflife.com/]]. It's an online publication focusing on news from a different perspective, which is much more sensical, and absolutely useful: >There are two ways of looking at things: picking out what’s unique, and being attentive to what’s recurring. The news is based on the former, philosophy on the latter. Which means that the daily diet of information and opinion tends to miss much. News, we concluded, is really what you need to know now, rather than what has just happened. The ideas of the [[Stoics|http://thephilosophersmail.com/perspective/the-great-philosophers-2-the-stoics/]] or of [[Lao Tzu|http://thephilosophersmail.com/perspective/the-great-eastern-philosophers-lao-tzu/]] might be urgent news in our lives, even though they have been around in the cultural ether for two millennia. And the List: ''RESILIENCE'' Keeping going even when things are looking dark; accepting that reversals are normal; remembering that human nature is in the end tough. Not frightening others with your fears. ''EMPATHY'' The capacity to connect imaginatively with the sufferings and unique experiences of another person. The courage to become someone else and look back at yourself with honesty. ''PATIENCE'' We lose our temper because we believe that things should be perfect. We’ve grown so good in some areas (putting men on the moon etc.), we’re ever less able to deal with things that still insist on going wrong; like traffic, government, other people... We should grow calmer and more forgiving by getting more realistic about how things actually tend to go. ''SACRIFICE'' We’re hardwired to seek our own advantage but also have a miraculous ability, very occasionally, to forego our own satisfactions in the name of someone or something else. We won’t ever manage to raise a family, love someone else or save the planet if we don’t keep up with the art of sacrifice. ''POLITENESS'' Politeness has a bad name. We often assume it’s about being ‘fake’ (which is meant to be bad) as opposed to ‘really ourselves’ (which is meant to be good). However, given what we’re really like deep down, we should spare others too much exposure to our deeper selves. We need to learn ‘manners’, which aren’t evil - they are the necessary internal rules of civilisation. Politeness is very linked to tolerance, the capacity to live alongside people whom one will never agree with, but at the same time, can’t avoid. ''HUMOUR'' Seeing the funny sides of situations and of oneself doesn’t sound very serious, but it is integral to wisdom, because it’s a sign that one is able to put a benevolent finger on the gap between what we want to happen and what life can actually provide; what we dream of being and what we actually are, what we hope other people will be like and what they are actually like. Like anger, humour springs from disappointment, but it’s disappointment optimally channelled. It’s one of the best things we can do with our sadness. ''SELF-AWARENESS'' To know oneself is to try not to blame others for one’s troubles and moods; to have a sense of what’s going on inside oneself, and what actually belongs to the world. ''FORGIVENESS'' Forgiveness means a long memory of all the times when we wouldn’t have got through life without someone cutting us some slack. It’s recognising that living with others isn’t possible without excusing errors. ''HOPE'' The way the world is now is only a pale shadow of what it could one day be. We’re still only at the beginning of history. As you get older, despair becomes far easier, almost reflex (whereas in adolescence, it was still cool and adventurous). Pessimism isn’t necessarily deep, nor optimism shallow. ''CONFIDENCE'' The greatest projects and schemes die for no grander reasons than that we don’t dare. Confidence isn’t arrogance, it’s based on a constant awareness of how short life is and how little we ultimately lose from risking everything.
Sir Terence David John "Terry" Pratchett, OBE (Order of the British Empire) was an English author of fantasy novels, especially comical works.
<<list-links "[tag{!!title}]">>
I call my Dad on the phone a few times a week (Skype is great!). He is 92 years old, and has been teaching high school math and physics for many years. Maybe that's where both I and my oldest daughter got the "education bug" from. He has never been very talkative, but with age he became even less so, so every time he has a "dad story" to tell, I treat it as a "special and tasty morsel". Being very associative, it always reminds me in different ways, of who and how he used to be when he was younger (and I was, too... ;-). Anyway, today he remembered a time when he was announcing in class the date for the next physics test. There was the usual excitement and groaning, and then a few students had the bright idea of asking my Dad for "a test with open books". Now, this was in the mid-70's, in the pre-Internet era, when books where //the// source of information and knowledge; "everything was in the book" (the equivalent of "it's on the web", or "there is an app for that", nowadays). The expectation was that students will study //everything// from the textbook, and be able to show what they absorbed from the book on the test. An "open book test" was unheard of. Also, my father was brought up and educated in Europe (in part of the then ~Austro-Hungarian Empire) under a system strongly influenced by German philosophy and pedagogy. Textbooks where treated then as "Bibles" -- reading //and// memorizing books (not just science, but literature and poetry, too) was "the effective thing to do" if you "really" wanted to learn. But, as he had told me many times when I grew up: there is reading, and then there is //reading//... (and then again, [[there is reading, too...|Knowing how to read]]). So, here is my father standing in front of the class, facing this dilemma of "to read (during the test), or not to read". His students probably took this proposal as a joke or a dare, but he considered it seriously. Despite his relatively strict upbringing -- my Dad was actually somewhat mischievous as an adolescent, and according to him, he wasn't really into his studies (but rather much more into sports. This did not, however, prevent him from earning a Ph.D. later in life :) -- he could definitely relate to the students' request for "open books" (and their way of thinking, you know, "everything is in the book; see a question on the test, find a similar one in the book; what can go wrong?") He also has, and always had, a good (sharp, but sometimes very subtle, barely detectable) sense of humor. //And//, most importantly (and more dangerously in this case -- more on this in a moment), ''he was a good reader!'' To make a long story short (where's the fun in that? ;-), my Dad agreed to this radical idea of an open book test in physics, to the loud approval of the entire class. As it turns out (surprise, surprise), my Dad knew the physics textbook "back-to-front, front-to-back, and upside-down" ([[HA!|Knowing how to read]]). I don't think he knew it as well as the Talmudic Scholars of the past knew the [[Talmud|http://en.wikipedia.org/wiki/Talmud]], but he knew it pretty well. BTW, and speaking of the Talmudic Scholars, it is said that you could stick a pin (a sacrilegious act in this context, but let's go with the story, shall we?) anywhere, on any page in the Talmud, and they could tell you, not only the sentence the pin hit on //the other side (the back side)// of the page, but the actual letter (!) in that sentence on that back page! As a result of this close and attentive reading, my father knew of 3 exercises in the physics textbook, which had an error in the answer in the back of the book, and (sure enough) these were the questions on the test ... (with slight variations :). Let's just say that the students did not excel on this test. I know what you are thinking... and my father thought so, too: "it was unfair, so after the students had taken it, I canceled the test, and gave another one, the following week", he said. But, back to "normal" -- a closed book test. As my Dad sums this (meta-lesson) up: "You have to know how to read!" Now that I think about it, it was quite a clever idea on my father's part, since the students ended up studying the material twice... Anyway, his story on the phone today, reminded me of a somewhat similar story from //my// university days. For better or for worse, I graduated from the Technion, which is the top engineering university in Israel; a high-achieving, highly competitive school in Haifa, which is a pretty industrialized city. One of the city landmarks was [[a pair of very high, massive chimneys|https://www.dreamstime.com/editorial-stock-image-oil-refineries-ltd-haifa-israel-isr-apr-its-vast-petrochemical-plants-have-released-significant-amounts-pollution-to-image55602154]] belonging to the dominant oil refinery in the city. One of the engineering courses in the faculty of Civil Engineering at the Technion had a project every quarter to determine the exact height of the two chimneys by doing __remote__ measurements from the Technion campus and using trigonometry to calculate the result. Since most Technion students are very busy and stressed out (but resourceful), //virtually all// students in that civil engineering course had been copying the results from previous years' papers for years, and everyone had been happy -- including the professor, who, I'm sure was pleased with the high consistency and accuracy of the results over so many years and generations of students. Until...one quarter, one student decided to //actually do// the remote measurements and calculations. And, he got different results from previous years... Needless to say, this student got an "F" on his project (can you really blame the professor?! ;-) Again, to cut a long story short, the student insisted that the professor join him in repeating the actual measurements and calculations, proved their correctness and ended up getting an "A". But you can imagine the mess trying to figure out what to do about all other students in the class (who originally got "A"s); and what do you do about past classes/generations/grades? As I said: a mess. But, again, as before, even when copying -- you have to know how to read. I would have summed it up a bit differently -- you have to know how to //think//, but I think that this is what my Dad meant, too, that you really have to develop a habit of //thoughtful reading//, critical reading, piercing reading (no relation to the Talmud pin pricking :), and that relying on books as Bibles (or Talmuds), and taking what's written in them on blind faith (or superficial understanding), is __not__ the way to truly learn and know. You have to ''own'' and internally re-create what you read. I am thankful to my father for having taught me that, and (in his subtle way) reminding me of it today.
The [[Edgie, Daniel Dennett|https://www.edge.org/memberbio/daniel_c_dennett]], is [[talking about his recovery from a serious heart failure|https://www.edge.org/conversation/daniel_c_dennett-thank-goodness]], and contemplates on being grateful (and to whom/what). (compared with [[Kurt Vennegutt's sentiment|If this isn’t nice, what is?]]) >The best thing about saying thank goodness in place of thank God is that there really are lots of ways of repaying your debt to goodness—by setting out to create more of it, for the benefit of those to come. Goodness comes in many forms, not just medicine and science. Thank goodness for the music of, say, Randy Newman, which could not exist without all those wonderful pianos and recording studios, to say nothing of the musical contributions of every great composer from Bach through Wagner to Scott Joplin and the Beatles. Thank goodness for fresh drinking water in the tap, and food on our table. Thank goodness for fair elections and truthful journalism. If you want to express your gratitude to goodness, you can plant a tree, feed an orphan, buy books for schoolgirls in the Islamic world, or contribute in thousands of other ways to the manifest improvement of life on this planet now and in the near future. On the lighter side, (but not less deep and useful!), and talking about simple, pure gratitude and appreciation, Terry Pratchett, in his excellent book [["A Hat Full of Sky"|http://discworld.wikia.com/wiki/A_Hat_Full_of_Sky]] describes an exchange between Tiffany (a young witch) and the old, powerful, and majestic witch Esme (Granny) Weatherwax^^1^^: >“Your grandmother,” she said, “did she wear a hat?” >“What? Oh…not usually,” said Tiffany, still thinking about the big show. “She used to wear an old sack as a kind of bonnet when the weather was really bad. She said hats only blow away up on the hill.” >“She made the sky her hat, then,” said Granny Weatherwax. >“And did she wear a coat?” >“Hah, all the shepherds used to say that if you saw Granny Aching in a coat, it’d mean it was blowing rocks!” said Tiffany proudly. >“Then she made the wind her coat, too,” said Granny Weatherwax. “It’s a skill. Rain don’t fall on a witch if she doesn’t want it to, although personally I prefer to get wet and be thankful.” >“Thankful for what?” said Tiffany. >“That I’ll get dry later.” ---- ^^1^^ “Mistress Weatherwax was sort of the head witch, even though officially, “Witches are all equal. [They] don’t have things like head witches. That’s quite against the spirit of witchcraft.”
That's the thing about people who think they hate computers. What they really hate is lousy programmers.
I recently finished teaching a course at [[MIT|http://www.citizenschools.org/california/about/locations/]] (part of the [[Citizen Schools|http://www.citizenschools.org/california/]]) titled "Acing Racing". (Another course I did was [["Amazing Mazes"|The "Amazing Mazes" course]]) (Another course I did was [["Right on Target"|The "Right on Target" course]]) The goal of the 10 week course was to get middle school kids excited and interested in math, computer graphics/animation, and programming. I used an ~OpenSource math package called [[Sage|http://sagemath.org/]] to gradually have the kids build a program in Sage (using Python), to set up a race between 2 rockets with different speeds and head-starts, and animate their race to the finishline. (I also implemented a similar lesson plan using a [[different computer technology (Scratch)|Acing Racing - teaching some math and programming]]) In the process of building and running the race, the kids went from guessing which rocket will win the race (based on changing the initial conditions of the rockets), to actually calculating ''and explaining'' the results in mathematical terms and reasoning. |borderless|k |The 10 week course culminated in a WOW!, <br>which is a show-and-tell by the kids to parents/family, friends, <br>and guests:<br> <br>[[The WOW! plan outline|resources/CitizenSchools_WOW_plan.pdf]]|[img[Acing Racing competition|resources/acing_racing_small.gif][resources/Distance-speed-time problems_sage.html]]| |borderless|k !!!The final Python program that the kids used to demonstrate different race conditions. During the WOW! the kids show-cased the simulation and animation program they created: [[The Python-Sage Acing Racing program|./resources/AcingRacingProgram.png]] They also asked the audience for predictions ( playing a game of "who will win the race?"), and then explained the math leading to a correct prediction of winning/losing. This is an animated version of the simulation/animation program which the kids used to show different races: [[The full User Interface for running Acing Racing races|./resources/Distance-speed-time problems_sage.html]] This is a static (.gif) version of one race run, which the kids used to demonstrate and explain their distance-speed-time calculations: [[A result of running one Acing Racing race|./resources/AcingRacingOutput1.png]] !!!Core Math standards covered In this course, the following California core standards had been covered: * Number sense (in preparation for graphing distance-time graphs, positioning on the number line was covered) * Problem solving using the 4 basic operations, including order of operations (to calculate distance, speed, time) * Analyzing graphs rendered in 2D (including misleading graphs) * Plotting data in 2D graph form (distance, time) * Mathematical analysis (the interpretation of problem "givens" (e.g. distance head start, time delay)
I recently finished teaching a course at [[MIT|http://www.citizenschools.org/california/about/locations/]] (part of the [[Citizen Schools|http://www.citizenschools.org/california/]]) titled "Amazing Mazes". (Another course I did was [["Acing Racing"|The "Acing Racing" course]]) (Another course I did was [["Right on Target"|The "Right on Target" course]]) The goal of the 10 week course was to get middle school students excited and interested in math, computer graphics/animation, and programming (see [[course outline, lesson plans, and student activities/programs|http://employees.org/~hmark/courses/amazingmazes/index.html]]). I used an ~OpenSource computer programming environment/tool called [[NetLogo|http://ccl.northwestern.edu/netlogo/]] to gradually have the students build more and more complex mazes in ~NetLogo (using a [[Domain Specific Language (DSL)|http://martinfowler.com/tags/domain%20specific%20language.html]]^^1^^ I had created), then to explore and program (again, with [[a DSL I had created|./resources/NetLogo Maze walking DSL Spec.pdf]]) different ways (algorithms) to "walk the mazes" (or solve them), and finally use competitions to evaluate (and show off) the effectiveness and efficiency of their programs. In the process of building mazes and programming maze "walkers", the students developed a sense for [[different kinds and types of mazes|http://employees.org/~hmark/math/netlogo/amazing-mazes-maze-maker-3.html]]^^2^^ (and connected graphs representing them), the various levels of challenges in solving different mazes, and different ways of effectively (successfully) and efficiently (quickly) programming maze walking solutions. |borderless|k |The 10 week course culminated in a WOW!, <br>which is a show-and-tell by the students to parents/family, friends, <br>and guests:<br> <br>[[The WOW! plan outline|resources/Amazing Mazes - WOW plan.pdf]]|[img[Amazing Mazes competition|resources/Amazing Mazes Competition - small.png][resources/Amazing Mazes Competition.png]]| |borderless|k !!!The final ~NetLogo program that the students used in the WOW! to demonstrate an effective/successful maze walking (solving) program. During the WOW! the students asked for a volunteer from the audience to manually walk the maze and compete with their program. [[The NetLogo competition (image)|./resources/Amazing Mazes Competition.png]] [[The NetLogo competition (Java Applet)|http://employees.org/~hmark/math/netlogo/amazing-mazes-competition.html]] !!!Activities leading up to the WOW! competition |borderless|k |The [[scaffolding NetLogo program (Java Applet)|http://employees.org/~hmark/math/netlogo/amazing-mazes-builder-2.html]] the students used to __learn how to build mazes__<br><br><br><br><br>The [[NetLogo program (Java Applet) and user interface|http://employees.org/~hmark/math/netlogo/amazing-mazes-12.html]] which the students used to __develop, test, and demonstrate maze walking solutions__ (e.g., "left-hand walk"):<br><br>[[A result of running one maze walking program|resources/Amazing Mazes program.png]] in a simple maze<br>[[A result of running one maze walking program|resources/Amazing Mazes programming.png]] in a more complex maze|[img[Amazing Mazes maze building|resources/Amazing Mazes maze-small.png][resources/Amazing Mazes maze.png]]<br>[img[Amazing Mazes maze programming|resources/Amazing Mazes programming-small.png][resources/Amazing Mazes programming.png]]| |borderless|k !!!Core Math and Programming concepts covered In this course, the following core concepts had been covered: * Graphing and Cartesian coordinate space (in 2D) * Basic connected graph analysis (difference in maze complexity, challenges) * Basic programming concepts and commands (for maze creation and maze walking/solving) * Basic analysis of program effectiveness and efficiency !!!Computational Literacy/Thinking concepts covered This course lends itself to discussion and exercising skills in the following [[Computational Literacy/Thinking|A Framework for Computational Thinking, Computational Literacy]] areas: * Levels of abstraction ** Describing and manipulating mazes and walkers * Modeling and representation ** Networking equivalence, programs and algorithms * Algorithms and procedures ** Strategies and algorithms for solving/walking mazes * Automation ** Commands, loops, conditions, programs ---- ^^1^^ - a "vintage" (1986) article on [[little languages|resources/Bentley-little-languages.pdf]], AKA Domain Specific Languages (~DSLs) by Jon Bentley ^^2^^ - [[a site with a nice collection|http://www.logicmazes.com/index.html]] of different types of "logic mazes" by Robert Abbott
The following thought experiment demonstrates how reversing the thinking about cause and effect can lead to "amazing" conclusions: (see also [[the anthropic principle|http://en.wikipedia.org/wiki/Anthropic_principle]]^^1^^ and [[the anthropic bias|On Anthropic Bias, or Was the Universe Made for Us?]]). Here's a way to pick "the most amazingly lucky (talented? skilled? gifted? spooky?)" coin flipper in the world. This flipper can/did call correctly with no fail all results of flipping a coin (insert your number here, but for example's sake let's say ''10 times''). First, you start with 1,024 coin flippers and pair them up (so 512 pairs). Have one flipper in each pair call heads (and the other person call tails). Each pair flips the coin and the flipper who had correctly called it goes on to the next round. So in the second round you have 512 "winners" from the first round, paired up into 256 pairs, and you repeat the calling and flipping. At the end of 10 rounds (in our example), you end up with one "very skilled and astonishingly talented" flipper, who correctly called all flips, and therefore has a perfect track record! Most "amazing" indeed. This reminds me of a [[NetLogo|http://ccl.northwestern.edu/netlogo/]] program I wrote to [[experiment with "evolutionary programming"|Exploring genetic algorithms using NetLogo]] (AKA, genetic algorithms), where it is clear (by definition, at most, at the end of time :) that over time (generations), a "best-of-breed" program will (not may, but will, after infinitely many generations, at worst :) emerge that solves the problem at hand. The scientist/paleontologist [[Stephen Jay Gould|http://www.stephenjaygould.org/]] said about human evolution: >the pathways that have led to our evolution are quirky, improbable, unrepeatable and utterly unpredictable. Human evolution is not random; it makes sense and can be explained after the fact. But wind back life's tape to the dawn of time and let it play again and you will never get humans a second time. The excellent author and journalist Robert Wright [[describes this "astonishing" human path|Nonzero: The Logic of Human Destiny]] (he calls it an "evolutionary escalator") very succinctly, concluding that where the human race is today is another case of "unavoidable (i.e., highly likely) luck". I think that this way of swapping (confusing?) cause and effect is at the heart of the [[anthropic principle|http://www.anthropic-principle.com/]]^^1^^, and is captured nicely in the cartoon by [[Frank Modell|http://frankmodell.com/]] in The New Yorker: [img[Lovely Outdoors|resources/lovely outdoors 1.png][resources/lovely outdoors.png]] (see also the astonishingly (amazingly? :) similar [[explanation using flipped coins|The "astonishing" coincidence of our existence]]). ---- ^^1^^ See [[Nick Bostrom|http://www.nickbostrom.com/]] on the [[anthropic principle|http://www.anthropic-principle.com/?q=book/table_of_contents]]
I (finally :) came across ([[in BrainPickings|https://www.brainpickings.org/2014/09/24/the-edge-of-the-sky-roberto-trotta/]]) someone ([[Roberto Trotta|http://robertotrotta.com/]]) who explains away the perceived astonishment reflected in the [[anthropic principle|http://en.wikipedia.org/wiki/Anthropic_principle]].
Amazingly (astonishingly? :) he came up with an analogy involving [[flipping coins|The "astonishing skills" of a coin flipper]] :) :
Imagine for a minute the following situation.
You enter a room where you find a table with a large number of small, gray, round pieces on it — of the type that you can use to buy a coffee, or a paper, or to pay for parking. The ones with one head on one side and some other picture on the flip side.
Let’s say that there are four hundred of the gray pieces on the table. And they all show heads.
You would not believe for a second that they were all just thrown on the table and happened to land this way. Although this could happen, it would be a hard thing to accept.
It would be easier to imagine that someone had walked into the room before you and had put them all down like this, heads up, all four hundred of them.
The strange thing about the Dark Push is that it is a bit like the four hundred heads-up gray pieces in the room.
If the Dark Push were only a tiny bit larger than it is, then everything we see around us would be very different.
It is as if changing only one of the heads in the four hundred would make the entire world change.
Change the Dark Push by a little bit, and Star-Crowds could not form; none of the stars we see in the sky would be there; the Sun would not be there; our Home-World would not be there; and life, as we know it, could not be here.
We wouldn’t be here to talk about this in the first place.
So the question is: Who or what put down all four hundred heads exactly this way?
Some student-people came to believe that they could understand this by imagining more rooms. A very large number of rooms.
In each of them, the four hundred gray pieces are all thrown up in the air and flipped. And they land in some way, however they may.
In most of the rooms, some of pieces will land heads, and some won’t.
But if you have enough rooms, in the end you’ll find one room where all of the pieces have landed heads-up. Just like that.
There is no need to imagine anyone setting them up in this way.
It’s only a question of having enough rooms and trying them all.
And so the idea is that perhaps the All-There-Is [The Universe] is not all there is.
I recently finished teaching a course at [[MIT|http://www.citizenschools.org/california/about/locations/]] (part of the [[Citizen Schools|http://www.citizenschools.org/california/]]) titled "Right on Target". (Another course I did was [["Acing Racing"|The "Acing Racing" course]]) (Another course I did was [["Amazing Mazes"|The "Amazing Mazes" course]]) The goal of the 10 week course was to get middle school kids excited and interested in math, computer graphics/animation, and programming. I used an ~OpenSource math package called [[Easy Java Simulations (EJS)|http://www.um.es/fem/EjsWiki/pmwiki.php]] to gradually have the kids understand and simulate/experience some key factors that are important to projectile motion (e.g., gravity, air resistance, projectile velocity, angle, etc.). In the process of simulating aiming projectiles and trying to hit different targets, both on Earth and on the Moon, the kids went from guessing gravity, friction, initial speed, initial angle, etc., to actually calculating ''and explaining'' the results in math and physics terms and reasoning. |borderless|k |The 10 week course culminated in a WOW!, <br>which is a show-and-tell by the kids to parents/family, friends, <br>and guests:<br> <br>[[The WOW! plan outline|resources/Right On Target - WOW plan.pdf]]|[img[Right on Target competition|resources/ejs_trajectories_moon_45_small.png][resources/ejs_right_on_target.png]]| |borderless|k !!!The final Easy Java Simulations (EJS) program that the kids used to demonstrate different projectile/ballistic conditions. During the WOW! the kids asked the audience for predictions (which velocity and angle will hit the target), and then explained the math leading to a correct prediction: [[The Easy Java Simulations (EJS) program|./resources/ejs_right_on_target.png]] !!!Main concepts covered In this course, the following concepts had been covered: * If air resistance is negligible, the size, shape, and weight of free falling objects does not change their dropping speed, nor the time it takes them to hit the ground ** A [[video of a simple experiment|resources/GalileoFallingBodiesGravityDemo.mp4]] demonstrates the point, ''qualitatively''. ** Use of a [[Video Analysis Tool|http://www.compadre.org/osp/items/detail.cfm?ID=9687]], [[shows this point|Tracker video analysis - falling bodies]] ''quantitatively''. * [[Friction (air resistance)|./resources/ejs_air_resistance.png]] can play a big role in projectile trajectories, velocity, and time ([[Java Applet|http://employees.org/~hmark/math/ejs/freefall_with_air_resistance.html]]) * In projectile/ballistic motion, [[there is more than one angle|./resources/ejs_trajectories.png]] you can use to hit a target (with a given velocity) ([[Java Applet|http://employees.org/~hmark/math/ejs/RightOnTarget.html]]) * Certain behaviors "math rules", or "physics laws", for example that a 45 degree angle will cause a projectile to shoot the farthest, are "universal" and apply "everywhere" ([[on Earth|./resources/ejs_trajectories_earth_45.png]] and [[on the Moon|./resources/ejs_trajectories_moon_45.png]]) ([[Java Applet|http://employees.org/~hmark/math/ejs/RightOnTarget.html]]) * Math (and programs like [[velocity calculators|./resources/ejs_velocity_calculator.png]]) can be very handy in calculating how to hit a target (speed and angle), eliminating the need to guess !!!Core Math standards covered In this course, the following California core standards had been covered: * Number sense and scaling (in dealing with behavior and gravity on Earth vs. Moon) * Problem solving using the 4 basic operations (and square root), including order of operations (to calculate projectile speed and angle) * Analyzing graphs/trajectories rendered in 2D (including misleading graphs) * Mathematical analysis (the interpretation of problem "givens" (e.g. target distance, target height, projectile velocity and angle, gravity)
Richard Hamming tells this [[personally formative story|http://worrydream.com/refs/Hamming%20-%20Mathematics%20on%20a%20Distant%20Planet.pdf]] in his article "MATHEMATICS ON A DISTANT PLANET": !!! ... and its criticality in the real world ... >[This experience] shaped my opinions. [It] occurred at Los Alamos during WWII when we were designing atomic bombs. Shortly before the first field test (you realize that no small scale experiment can be done-either you have a critical mass or you do not), a man asked me to check some arithmetic he had done, and I agreed, thinking to fob it off on some subordinate. When I asked what it was, he said, “It is the probability that the test bomb will ignite the whole atmosphere.” I decided I would check it myself! > >The next day when he came for the answers I remarked to him, “The arithmetic was apparently correct but I do not know about the formulas for the capture cross sections for oxygen and nitrogen-after all, there could be no experiments at the needed energy levels.” He replied, like a physicist talking to a mathematician, that he wanted me to check the arithmetic not the physics, and left. I said to myself, “What have you done, Hamming, you are involved in risking all of life that is known in the Universe, and you do not know much of an essential part?” > >I was pacing up and down the corridor when a friend asked me what was bothering me. I told him. His reply was, “Never mind, Hamming, no one will ever blame you.” Yes, we risked all the life we knew of in the known universe on some mathematics. Mathematics is not merely an idle art form, it is an essential part of our society. And he concludes: >Many times I have made predictions about the physical world based on mathematics done at my desk. Surely Nature does not know nor care what I write, nor the mathematical postulates used, but the consequences can be serious. Therefore it is of significant importance to ask, "What kinds of mathematics can I depend on, and what kinds can I not?" That is the question! !!! ... but it's relation/relevance to the real world :) >I know that the great Hilbert said, "We will not be driven out of the paradise Cantor has created for us," and I reply, "I see no reason for walking in!" Indeed, in time, as more and more people get used to computers, I am inclined to believe that we here on this Earth will decide that the computable numbers are enough. Apparently you never need a non-computable number! > >Take, for example, the classic real line from 0 to 1, and remove the computable numbers. You have a non-countable number of numbers left, no one of which you can ever describe (how can you describe a number adequately if you cannot give, at least implicitly, a way of finding it)! Yet the axiom of choice says you can select one! > >Can you? Which one, if you can never describe it so another person knows what you are talking about? Is the axiom of choice reasonable? Is it safe to depend on this axiom in this real world? Just as the physicists finally decided, after years of arguing about properties of the ether that it turned out could not be measured, I too believe it is better to ignore entirely what you cannot talk about or measure! Some things do not arise naturally. (see also [[Is Math a human invention or a series of discoveries of truths in the real world?]])
<<list-links "[tag[The Accidental Universe - The World You Thought You Knew]!tag[book]]">>
In a (typical?) chain of events, I watched a ~TEDx talk by an educational games designer named Sean Bouchard called [[Chocolate Covered Broccoli: Building Better Games|http://www.youtube.com/watch?v=VrK7VXCfsS0&feature=relmfu]], and he mentioned Raph Koster's book //Theory of Fun//, which led me to a [[presentation by Raph|Theory of fun - Raph Koster]], where Raph shows a cartoon of Chris Crawford responding to Raph's (mis)quoting of Chris: Fun is just another word for learning. |borderless|k |[img[crawford 1|./resources/crawford11.png][./resources/crawford1.png]]1|[img[crawford 2|./resources/crawford21.png][./resources/crawford2.png]]2|[img[crawford 3|./resources/crawford31.png][./resources/crawford3.png]]3| |[img[crawford 4|./resources/crawford41.png][./resources/crawford4.png]]4|[img[crawford 5|./resources/crawford51.png][./resources/crawford5.png]]5|[img[crawford 6|./resources/crawford61.png][./resources/crawford6.png]]6| |borderless|k What Crawford is saying in the cartoon echoes the [[Song of Joy]] by Wang Ken about learning and happiness/joy, which I personally find very true, so... This led me to Chris's book [[The Art of Computer Game Design|resources/computer game design - chris crawford.pdf]] where he talks about his philosophy around game design, with quite a few implications about learning. In the introduction to the book, Crawford is pointing out that [[Those who overrate their own understanding undercut their own potential for learning.]] Learning (and living, too) requires (and is more enjoyable, if lived with) humbleness and curiosity, but also openness and admitting that knowledge/understanding is constantly evolving. It happens both on the personal/individual level, and to the human race (e.g. theories in physics and chemistry; discoveries, proofs, and extensions in math). Sometimes these are evolutions, and sometimes revolutions. As a game designer, Crawford wants to know: Why do people play games? What motivates them? What makes games fun? And he looks back to history and nature for answers. He points out the natural and deeply ingrained ability (necessity?) of humans and other animals to learn through play (and playing games), and as he indicates, games are a serious business. >A trip to the zoo will suffice. There we find two lion cubs wrestling near their mother. They growl and claw at each other. They bite and kick. One cub wanders off and notices a butterfly. It crouches in the grass, creeps ever so slowly toward its insect prey, then raises its haunches, wiggles them, and pounces. >... who knows if lions can have fun? But we are dead wrong on the last count. These cubs are not carefree. They do not indulge in games to while away the years of their cubhood. These games are deadly serious business. They are studying the skills of hunting, the skills of survival. They are learning how to approach their prey without being seen, how to pounce, and how to grapple with and dispatch prey without being injured. They are learning by doing, but in a safe way. And implications/parallels to education: >... Games are thus the most ancient and time-honored vehicle for education. They are the original educational technology, the natural one, having received the seal of approval of natural selection. We don't see mother lions lecturing cubs at the chalkboard; we don't see senior lions writing their memoirs for posterity. In light of this, the question, "Can games have educational value?" becomes absurd. It is not games but schools that are the newfangled notion, the untested fad, the violator of tradition. Game-playing is a vital educational function for any creature capable of learning. But Crawford is not claiming that education/learning is the only motivation for game playing: >I must qualify my claim that the fundamental motivation for all game-play is to learn. First, the educational motivation may not be conscious. Indeed, it may well take the form of a vague predilection to play games. The fact that this motivation may be unconscious does not lessen its import; indeed, the fact would lend credence to the assertion that learning is a truly fundamental motivation. >Second, there are many other motivations to play games that have little to do with learning, and in some cases these secondary motivations may assume greater local importance than the ancestral motivation to learn. These other motivations include: fantasy/exploration, nose-thumbing, proving oneself, social lubrication, exercise, and need for acknowledgment. I shall examine each in turn. Crawford is comparing games to simulations, and starts with a definition of a game: >A game is a closed formal system that subjectively represents a subset of reality. Then, he looks at representation (subjective vs. objective): >Representation is a coin with two faces: an objective face and a subjective face. The two faces are not mutually exclusive, for the subjective reality springs from and feeds on objective reality. In a game, these two faces are intertwined, with emphasis on the subjective face. For example, when a player blasts hundreds of alien invaders, nobody believes that his recreation directly mirrors the objective world. However, the game may be a very real metaphor for the player's perception of his world. I do not wish to sully my arguments with pop psychological analyses of players giving vent to deep seated aggressions at the arcades. Clearly, though, something more than a simple blasting of alien monsters is going on in the mind of the player. We need not concern ourselves with its exact nature; for the moment it is entirely adequate to realize that the player does perceive the game to represent something from his private fantasy world. Thus, a game represents something from subjective reality, not objective. Games are objectively unreal in that they do not physically recreate the situations they represent, yet they are subjectively real to the player. The agent that transforms an objectively unreal situation into a subjectively real one is human fantasy. Fantasy thus plays a vital role in any game situation. A game creates a fantasy representation, not a scientific model. Crawford brings up an interesting point about the nature of the mental processes and experience of a game player as they play. Crawford describes one "emotional response" of this "subjective flow", namely that some //fantastic// happenings in the game resonate with the player's private/subjective reality/world. But another "emotional response" that can be evoked, especially in the context of an educational game can be curiosity (sometimes incredulity, puzzlement, desire to know, as [[observed by Isaac Asimov|The most exciting phrase to hear in science, the one that heralds new discoveries, is not "Eureka!", but "That's funny...".]]), or sense of accomplishment (sometimes satisfaction, [[joy|Song of Joy]], pleasure). And, compares games to simulations: >The distinction between objective representation and subjective representation is made clear by a consideration of the differences between simulations and games. A simulation is a serious attempt to accurately represent a real phenomenon in another, more malleable form. A game is an artistically simplified representation of a phenomenon. The simulations designer simplifies reluctantly and only as a concession to material and intellectual limitations. The game designer simplifies deliberately in order to focus the player's attention on those factors the designer judges to be important. The fundamental difference between the two lies in their purposes. A simulation is created for computational or evaluative purposes; a game is created for educational or entertainment purposes.(There is a middle ground where training simulations blend into educational games.) Accuracy is the sine qua non of simulations; clarity the sine qua non of games. >A simulation bears the same relationship to a game that a technical drawing bears to a painting. A game is not merely a small simulation lacking the degree of detail that a simulation possesses; a game deliberately suppresses detail to accentuate the broader message that the designer wishes to present. Where a simulation is detailed a game is stylized. I think that Crawford makes good points about the main characteristics and differences between games and simulations. But, a simulation, especially for purposes of education/learning, can be done at various levels of accuracy/fidelity, depending on the educational objectives. (I think that Crawford's observation that a "simulation is created for computational or evaluative purposes" refers to one kind/level of simulation). So for example, there can be a simulation within a domain to clarify the main concepts and principles, which will be different from a simulation (in the same domain, covering the same topic/area) aimed at teaching some skills and analysis techniques. Crawford would not disagree with the above, as he realizes that the goal/objective should drive the design of the game, which is doubly true for educational games: >A game must have a clearly defined goal. This goal must be expressed in terms of the effect that it will have on the player. It is not enough to declare that a game will be enjoyable, fun, exciting, or good; the goal must establish the fantasies that the game will support and the types of emotions it will engender in its audience. Since many games are in some way educational, the goal should in such cases establish what the player will learn. It is entirely appropriate for the game designer to ask how the game will edify its audience. It's interesting to compare what Todd Blayone has to say about [[Gamification in education]]
A couple of days ago, I attended an [[interesting lecture by Paul Saffo|http://events.stanford.edu/events/339/33941/]] (he calls himself a futurist), where he talked about the "creator economy" (which according to him is the next type of economy, after the industrial economy, and the consumer economy). I decided to follow up on him on [[his website|http://www.saffo.com/]] which led me to an article on [[Edge|http://edge.org/]] about [[A third kind of knowledge|http://edge.org/response-detail/144/how-is-the-internet-changing-the-way-you-think]]. Here he mentioned: >Back in the mid-1700s, Samuel Johnson observed that there were two kinds of knowledge: that which you know, and that which you know where to get. This echos what I put on [[my Master's degree website|http://ldtprojects.stanford.edu/~hmark/]] about Francis Bacon's famous saying: "knowledge is power". As I had said there, access to knowledge is powerful, but timing is critical, so it actually boils down to: ''timely'' access to knowledge is power. Saffo continues: >Johnson's insight was crucial because until then scholars relied heavily on the first kind of knowledge, the ability to know and recall scarce information. Abundant print usurped this task and in the process created the need for a new skill i.e., Johnson's knowing "where to get it." Two asides here, which are talking about the art of memory: * I just finished reading the book //Little, Big// by John Crowley, and I enjoyed it a lot! It's //wonder//ful! It has this "softly magical" feeling to it (it is a "fairytale" after all), and it contains "Prose that F. Scott Fitzgerald would envy... the best fantasy yet written by an American." (from the "Praise for" page of the book). In the book, Crowley talks about [[Giordano Bruno|http://en.wikipedia.org/wiki/Giordano_Bruno]], [[The art of memory|http://en.wikipedia.org/wiki/Art_of_memory]], and the mnemonic devices one of the characters (Ariel Hawksquill) is using to remember prodigious amounts of details and relationships. * Patrick Hutton has [[a very insightful article|Hutton - The Art of Memory.pdf]] on the art of memory, with both some history of what, why and how memory devices had been used in the past, as well as a psychoanalysis twist at the end. Back to Saffo: >As the store of paper-based knowledge grew, the new skill of research displaced the old skill of recall. A scholar could no longer get by on memory alone i.e., one had to know where and how to get knowledge. >Now the Internet is changing how we think again...Knowing where to get is now the domain of machines, not humans. While I agree that the Internet is causing a big change, I don't think it's necessarily changing "how we think", but rather the how we "feed" our thinking processes (with knowledge). Although, to the extent that //how// and //what// we (or The Machines (a-la "The Matrix"), or the Internet, e.g. Google) feed and //filter// the information that reaches us, it changes //what// we think, for sure. And he continues: >The Internet is changing our thinking by giving the tremendous power of search to the most casual of users. We have democratized knowledge-finding in the same way 18th century publishing democratized knowledge access. Referring to the effect of publishing: if the claimed effect is on //how// we think, I'd claim it's a bit of a stretch. But, if we include in publishing the development of [[new notations|The power of a new literacy]], and the development of [[new literacies|Computing Literacy]], then I agree that publishing (through these!) has affected the way we think. Since searching in the age of the Internet became so easy, there is a new danger: >Couch potatoes who once channel-surfed their way through TV's vast wasteland have morphed into mouse potatoes Google-surfing the vaster wasteland of Cyberspace. They are wasting their time more interactively, but they are still wasting their time. >The Internet has changed our thinking, but if it is to be a change for the better, we must add a third kind of knowledge to Johnson's list i.e., the knowledge of what matters...Without a discipline of knowing what matters, we will merely amuse ourselves to death. And Saffo concludes: >Knowing what matters is more than mere relevance. It is the skill of asking questions that have purpose, that lead to larger understandings. Formalizing this skill seems as strange to us today as a dictionary must have seemed in 1780, but I'll bet it emerges just as surely as print abundance led to whole new disciplines devoted to organizing information for easy access. The need to determine what matters will inspire new modes of cyber-discrimination and perhaps even a formal science of determining what matters. Social media hold great promise as discrimination tools, and AI hints at the possibility of cyber-Cicerones who would gently keep us on track as we traverse the vastness of cyberspace in our enquiries. Perhaps the 21st century equivalent of the Great Dictionary will be assembled by a wise machine that knows what matters most. I find parts of this final vision not really forward looking, but rather looking back (and maybe that's one of the tricks of good futurists!). For example, the prediction (hope?) that a new science of determining what matters will emerge. Even though, it seems to me, that it's really an old wine in a new bottle. Didn't the Greeks coin the terms "ethics" and "morality" to mean the same thing? Will we not have to determine //why// things matter, before we can say //what// matters? And I'm not sure it'll be such an exciting future if machines (even if wise and gentle) will know what matters most (and without sounding too paranoid: matters most to //whom//?) On the other hand, I still remember the worries people had about personal calculators "taking over" and making humans (and students) "arithmetic imbeciles". It didn't really happen, although it may be true that many people and children today are weaker in mental arithmetic/math. On the point about needing to evolve out of "bad searching", here's what [[Kai Krause|http://www.byteburg.de/]] has to say about it on [[Edge|http://www.edge.org/3rd_culture/hillis10/hillis10_index.html#krause]]: >Google may find keywords from billions of pages within fractions of seconds...but then it dumps them in a rather silly list which takes hundreds of seconds to make sense of, scroll, page, examine. And much of it is pure content junk, a lot of it is paid-for junk. Truly getting useful results from any search engine is actually a fine art form in itself. (But far be it for me to complain though, I craved these tools forever.). It is not hard to state the obvious: there should be much less emphasis on memorizing facts and figures, but rather teach how to find them, how to use all available options and tools. (BTW, the context is [["ARISTOTLE" and "THE KNOWLEDGE WEB"|http://www.edge.org/3rd_culture/hillis10/hillis10_index.html]] by W. Daniel Hillis)
In an article titled [[The Great Forgetting|http://www.theatlantic.com/magazine/archive/2013/11/the-great-forgetting/309516/]] in The Atlantic magazine, Nicholas Carr (of [[Is Google Making Us Stupid?|http://www.theatlantic.com/magazine/archive/2008/07/is-google-making-us-stupid/306868/]] fame) brings up important points about the value //and harm// of automation, to human abilities and skills, saying on one hand: >Every time we off-load a job to a tool or a machine, we free ourselves to climb to a higher pursuit, one requiring greater dexterity, deeper intelligence, or a broader perspective. We may lose something with each upward step, but what we gain is, in the long run, far greater. But warns, that on the other hand: >Rather than opening new frontiers of thought and action, software ends up narrowing our focus. We trade subtle, specialized talents for more routine, less distinctive ones. >Most of us want to believe that automation frees us to spend our time on higher pursuits but doesn’t otherwise alter the way we behave or think. That view is a fallacy—an expression of what scholars of automation call the “substitution myth.” A labor-saving device doesn’t just provide a substitute for some isolated component of a job or other activity. It alters the character of the entire task, including the roles, attitudes, and skills of the people taking part. As Parasuraman and a colleague explained in a 2010 journal article, “Automation does not simply supplant human activity but rather changes it, often in ways unintended and unanticipated by the designers of automation.” All of which is absolutely true. Automation, if done well, may/will change processes, procedures, and roles. Automation, like improvement/refinement, is a powerful human ability and mechanism, and as any other powerful "tool" should be used carefully and judiciously. We have to be careful not to throw the baby with the bathwater. Just as a couple of trivial examples of where automation (of calculation, in this example) definitely did not hurt, and indeed freed up mental cycles to do higher-level activities are the manual technique of calculating the square root of a number (in math lessons at school), and using logarithms to calculate things (in engineering). It's pretty clear that the knowledge of doing these tasks "has been lost", but the fact that we understand the meaning of square roots and know how/when to use them, and the fact that we can use calculators/computers to do arithmetic without resorting to logarithms, brought many benefits to human evolution. At the end of the article Carr brings up an important philosophical question about human nature or essence, and how integral is learning and knowing to human nature. >Whether it’s a pilot on a flight deck, a doctor in an examination room, or an Inuit hunter on an ice floe, knowing demands doing. One of the most remarkable things about us is also one of the easiest to overlook: each time we collide with the real, we deepen our understanding of the world and become more fully a part of it. While we’re wrestling with a difficult task, we may be motivated by an anticipation of the ends of our labor, but it’s the work itself—the means—that makes us who we are. Computer automation severs the ends from the means. It makes getting what we want easier, but it distances us from the work of knowing. As we transform ourselves into creatures of the screen, we face an existential question: Does our essence still lie in what we know, or are we now content to be defined by what we want? If we don’t grapple with that question ourselves, our gadgets will be happy to answer it for us. While I can understand Carr's point about the strong allure and pull of satisfying all our wants/wishes immediately, it's pretty clear to me that curiosity, and therefore learning, and therefore knowing is embedded in our nature and therefore is part of the definition of who we are. If anything, instant gratification is a strong motivator (and reward), and as such is also part of who we are (so it's not a case of one ''or'' the other, but rather one ''and'' the other, that define us). But again, Carr has a point about the dangers of falling into a trap of focusing on the reward and not be willing or able to do and enjoy the journey.
^^*^^ as defined by the College Board for the [[Advanced Placement Computer Science Principles|https://secure-media.collegeboard.org/digitalServices/pdf/ap/ap-computer-science-principles-course-and-exam-description.pdf]] (AP CSP) course !!!Computer Science Principles - "Big Ideas" Big Idea 1: Creativity. Computing is a creative activity. Big Idea 2: Abstraction. Abstraction reduces information and detail to facilitate focus on relevant concepts. Big Idea 3: Data and information. Data and information facilitate the creation of knowledge. Big Idea 4: Algorithms. Algorithms are used to develop and express solutions to computational problems. Big Idea 5: Programming. Programming enables problem solving, human expression, and creation of knowledge. Big Idea 6: The Internet. The Internet pervades modern computing. Big Idea 7: Global Impact. Computing has global effects on individuals and society. !!!Computer Science Principles - Practices and Skills Practice 1: Connecting computing (Making connections to and from the real world; making connections within CS) Practice 2: Creating computational artifacts Practice 3: Abstracting Practice 4: Analyzing problems and artifacts Practice 5: Communicating Practice 6: Collaborating
In a good article in Nature Journal titled [[Can we open the black box of AI?|http://www.nature.com/news/can-we-open-the-black-box-of-ai-1.20731]] Davide Castelvecchi brings up an important aspect (and caution) to consider, as we (rush to) trust Artificial Intelligence (AI) and Machine Learning to make more (and more critical) decisions in our lives. The fundamental problem is that some implementations of AI (e.g., neural networks) are opaque about what they learned, and it's very hard, or sometimes impossible to back-track and figure out how they reached a certain conclusion or why they behaved a certain way. >“The problem is that the knowledge gets baked into the network, rather than into us,” says Michael Tyka, a biophysicist and programmer at Google in Seattle, Washington. “Have we really understood anything? Not really -- the network has.” And it boils down to: can we trust these systems and algorithms if we don't understand (and cannot find out?) how they learned and why they behave the way they do. It's similar to the dilemma an investor faces when thinking about a (in)famous "investment strategy" known as The Super Bowl Stock Market Indicator. As [[a BBC article|http://www.bbc.com/news/business-21277122]] puts it: >Prof George Kester, of Washington and Lee University, estimates that if since 1967 (the first year the Super Bowl was played) he'd invested $1,000 in the stock market each year the indicator predicted an up market, and switched the money over to bonds every year that the indicator predicted a down market, he would have $168,053 today. A classic (and "oldie but goodie") example from the Cold War era is the attempts of the US to create an intelligent system which identifies Russian tanks on the battlefield, in order to alert NATO forces about friends vs. foes. As part of the system training/learning sessions, the US scientists fed the system with hundreds of tank images/photos of both friendly and enemy tanks. But when it came to battlefield testing, the system failed miserably. With great effort, the scientists backtracked the system's learning patterns and decision criteria, and found out that since the majority of the enemy tank images had been photographed at night and/or under severe weather conditions (and the Allied tank images were photographed under favorable lighting and weather conditions), the system actually learned to distinguish weather conditions, not tank shapes and models. The article in Nature gives a similar (and more "modern" example), where a computer scientist was teaching a car to drive autonomously: >On each trip, Pomerleau [the scientist] would train the system for a few minutes, then turn it loose to drive itself. Everything seemed to go well — until one day the Humvee approached a bridge and suddenly swerved to one side. He avoided a crash only by quickly grabbing the wheel and retaking control. >Back in the lab, Pomerleau tried to understand where the computer had gone wrong. “Part of my thesis was to open up the black box and figure out what it was thinking,” he explains. But how? He had programmed the computer to act as a 'neural network' -- a type of artificial intelligence (AI) that is modelled on the brain, and that promised to be better than standard algorithms at dealing with complex real-world situations. Unfortunately, such networks are also as opaque as the brain. Instead of storing what they have learned in a neat block of digital memory, they diffuse the information in a way that is exceedingly difficult to decipher. Only after extensively testing his software's responses to various visual stimuli did Pomerleau discover the problem: the network had been using grassy roadsides as a guide to the direction of the road, so the appearance of the bridge confused it. So, >Issues such as these have led some computer scientists to think that deep learning with neural networks should not be the only game in town. Zoubin Ghahramani, a machine-learning researcher at the University of Cambridge, UK, says that if AI is to give answers that humans can easily interpret, “there's a world of problems for which deep learning is just not the answer”. One relatively transparent approach with an ability to do science was debuted in 2009 by Lipson and computational biologist Michael Schmidt, then at Cornell University in Ithaca, New York. Their algorithm, called Eureqa, demonstrated that it could rediscover the laws of Newtonian physics simply by watching a relatively simple mechanical object — a system of pendulums — in motion4. > >Starting from a random combination of mathematical building blocks such as +, −, sine and cosine, Eureqa follows a trial-and-error method inspired by Darwinian evolution to modify the terms until it arrives at the formulae that best describe the data. It then proposes experiments to test its models. One of its advantages is simplicity, says Lipson. “A model produced by Eureqa usually has a dozen parameters. A neural network has millions.” The bottom line is that there is no single answer/solution/silver bullet to devising and deploying intelligent machines: >the complex answers given by machine learning have to be part of science's toolkit because the real world is complex: for phenomena such as the weather or the stock market, a reductionist, synthetic description might not even exist. “There are things we cannot verbalize,” says Stéphane Mallat, an applied mathematician at the École Polytechnique in Paris. “When you ask a medical doctor why he diagnosed this or this, he's going to give you some reasons,” he says. “But how come it takes 20 years to make a good doctor? Because the information is just not in books.” > >[...] scientists should embrace deep learning without being “too anal” about the black box. After all, they all carry a black box in their heads. “You use your brain all the time; you trust your brain all the time; and you have no idea how your brain works.” But as [[John Seely Brown (formerly at Xerox and then at Stanford) paints the picture|Sense-making and learning in the new 21st century environment]], we will blend more and more "Homo Sapiens" (knowing man) with "Homo Faber" (maker man) with "Homo Ludens" (player man) and AI (Artificial Intelligence) and IA (Intelligent Augementation), and it will become more and more important to understand this "new way of being".
In a well-thought-out [[blog post titled The Case for Slow Programming|https://ventrellathing.wordpress.com/2013/06/18/the-case-for-slow-programming/]], [[Jeffrey Ventrella|https://ventrellathing.wordpress.com/about/]] starts by quoting his father: >“Slow down, son. You’ll get the job done faster.” which reminds me of a quote ([[if I say so myself|I'll understand quickly if you explain slowly.]] :) "if you explain slowly, I'll understand quickly" In the post, Ventrella, who is a programmer/artist over 55, makes some good points: * I program slowly and thoughtfully. I’m kind of like a designer who writes code. * You can’t wish away [the] Design Process [by doing quick and small iterations, committing code frequently and not breaking anything in the process]. It has been in existence since the dawn of civilization. And the latest clever development tools [e.g., github], no matter how clever, cannot replace the best practices and real-life collaboration that built cathedrals, railroads, and feature-length films. He describes his programming style/process: * My programming style is defined by organic arcs of different sizes and timescales, Each arc starts with exploration, trial and error, hacks, and temporary variables. Basically, a good deal of scaffolding. A picture begins to take shape. Later on, I come back and dot my i’s and cross my t’s. The end of each arc is something like implementation-ready code. (“Cleaning my studio” is a necessary part of finishing the cycle). The development arc of my code contribution is synonymous with the emergence of a strategy, a design scheme, an architecture. * And sometimes, after a mature organism has emerged, I go back and start over, because I think I have a better idea of how to do it. Sometimes I’m wrong. Sometimes I’m right. There is no way to really know until the organism is fully formed and staring me in the face. * The "slow programming movement" is part of a more general "slow movement". It is a software development philosophy that emphasizes careful design, quality code, software testing and thinking. It strives to avoid kludges, buggy code, and overly quick release cycles. * As part of the agile software development movement, groups of software developers around the world look for more predictive projects, and aiming at a more sustainable career and work-life balance. They propose some practices such as pair programming, code reviews, and code refactorings that result in more reliable and robust software applications. * Money dynamics puts unnatural demands on a process that would be best left to the natural circadian rhythms of design evolution. Fast is not always better. In fact, slower sometimes actually means faster – when all is said and done. The subject of how digital technology is usurping our natural temporal rhythm is addressed in Rushkoff’s [[Present Shock|http://www.rushkoff.com/books/present-shock/]]. > * ''I believe that we need older people, women, and educators INSIDE the software development cycle. More people-people, fewer thing-people. And I don’t mean on the outside, sitting at help desks or doing UI flower arranging. I mean on the INSIDE – making sure that software resonates with humanity at large.'' > * “software programming is not typing” (and Brendan Enrick has more to say about this[[|http://brendan.enrick.com/post/Programming-is-Not-Just-Typing]]. Everyone knows this, but it doesn’t hurt to remind ourselves every so often. * The fact that we programmers spend our time jabbing our fingers at keyboards makes it appear that this physical activity is synonymous with programming. But programming is actually the act of bringing thought, design, language, logic, and mental construction into a form that can be stored in computer memory.
[[from The chess mentality|http://www.research.ibm.com/deepblue/learn/html/e.8.4.html]] by William H. Calvin compare to [[The end of an era, the beginning of another? HAL, Deep Blue and Kasparov|The end of an era, the beginning of another? HAL, Deep Blue and Kasparov]] Some animals have gotten to be so fancy that they simulate a course of action before taking even a tentative first step. The chess master, who looks a half-dozen moves ahead, is a prime example as is the army general or poker player who thinks through bluff and counterbluff before acting. These are only extreme examples of how to make and compare alternative plans, but they illustrate the same sort of process that we all go through when simply contemplating the leftovers in the refrigerator, trying to figure out a combination that will avoid another trip to the grocery store. Many animals look ahead in a limited way, predicting when winter is coming. But that requires only the simplest of nighttime-length-sensitive hormonal mechanisms, not even a brain. It's a novel course of action, one that neither you nor any of your ancestors has done before, that is the difficult part. And not even that is hard, if you have the time to grope around. A goal, and some feedback about progress, suffices for many novel situations. But if I have to pick up a cup of uncertain weight and bring it to my lips in less than a quarter of a second, feedback doesn't have time to help and so I'll hit my nose if I haven't made the perfect plan in advance. Personally, I think that the extensive planning needed for such ballistic movements as throwing, hammering, kicking, clubbing, and spitting has been very important in the ice age evolution of the human brain and that we use the same neural machinery for planning what to speak next, or listen to music, or to plan a dinner of leftovers. Creativity indeed, the whole high end of intelligence and consciousness involves playing mental games that shape up quality. Humans can simulate future courses of action and weed out the nonsense off-line. As the philosopher Karl Popper has said, this "permits our hypotheses to die in our stead." What sort of mental machinery might it take to do this mental feat? I suggest, in How Brains Think (Science Masters), that our brains perform a vastly speeded-up version of the same Darwinian process used in evolving new plant and animal species, the same process seen in the immune response in the days and weeks following a flu shot. In The Cerebral Code (MIT Press), I discuss the cerebral circuitry that does the job. By borrowing the mental structures for syntax to judge other combinations of possible actions, we can extend our plan-ahead abilities and our intelligence. To some extent, this is done by talking silently to ourselves, making narratives out of what might happen next, and then applying syntax-like rules of combination to rate a candidate scenario as dangerous nonsense, mere nonsense, possible, likely, or logical. But our intelligent guessing is not limited to language-like constructs; indeed, we may shout "Eureka!" when a set of mental relationships clicks into place, yet have trouble expressing this understanding verbally for weeks thereafter. What is it about human brains that allows us to be so good at guessing complicated relationships? We create sequences when we speak a sentence that we've never spoken before or improvise at jazz or plan a career. We invent dance steps. Even as four-year-olds, we can play roles, achieving a level of abstraction (that "willing suspension of disbelief") not seen in even the smartest apes. Many of our beyond-the-apes behaviors involve novel strings of behaviors, often compounded: phonemes chunked into words, words into word phrases, and (as in this paragraph) word phrases into complicated sentences with nested ideas. Rules for made-up games illustrate the memory aspect of this novelty: we must judge possible moves against serial-order rules, for example, in solitaire where you must alternate colors as you place cards in descending order. Preschool children will even make up such arbitrary rules, and then judge possible actions against them. We abandon many of the possible moves that we consider in a card game once we check them out against our serial-order memories of the rules. In shaping up a novel sentence to speak, we are checking our candidate word strings against overlearned ordering rules that we call syntax and grammar. Our plan-ahead abilities gradually develop from childhood narratives and are a major foundation for ethical choices, as we imagine a course of action, imagine its effects on others, and decide not to do it. That's the mentality that chess illustrates so well. Humanity wouldn't be human (or humane) without it. ---- copyright 1997 William H. Calvin William H. Calvin is a theoretical neurophysiologist at the University of Washington in Seattle. He is the author of nine books, including The Cerebral Code, How Brains Think, The River that Flows Uphill, and, with the neurosurgeon George A. Ojemann, Conversations with Neil's Brain. For a further discussion of these topics, visit William H. Calvin's Web site.
Steven Pinker, in his book “The Sense of Style” writes: >The main cause of incomprehensible prose is the difficulty of imagining what it’s like for someone else not to know something that you know. and this is also true about teaching. An expert is often not a good teacher. Or as the psychologist Sian Beilock, now the president of Barnard College, writes, “As you get better and better at what you do, your ability to communicate your understanding or to help others learn that skill often gets worse and worse.” The Harvard Business Review describes [[a simple and clear experiment|https://hbr.org/2006/12/the-curse-of-knowledge]] demonstrating the difficulty of transmitting knowledge from expert to novice, or teacher to learner: >In 1990, a Stanford University graduate student in psychology named Elizabeth Newton illustrated the curse of knowledge by studying a simple game in which she assigned people to one of two roles: “tapper” or “listener.” Each tapper was asked to pick a well-known song, such as “Happy Birthday,” and tap out the rhythm on a table. The listener’s job was to guess the song. > >Over the course of Newton’s experiment, 120 songs were tapped out. Listeners guessed only three of the songs correctly: a success ratio of 2.5%. But before they guessed, Newton asked the tappers to predict the probability that listeners would guess correctly. They predicted 50%. The tappers got their message across one time in 40, but they thought they would get it across one time in two. Why? > >When a tapper taps, it is impossible for her to avoid hearing the tune playing along to her taps. Meanwhile, all the listener can hear is a kind of bizarre Morse code. Yet the tappers were flabbergasted by how hard the listeners had to work to pick up the tune. > >The problem is that once we know something—say, the melody of a song—we find it hard to imagine not knowing it. Our knowledge has “cursed” us. We have difficulty sharing it with others, because we can’t readily re-create their state of mind. There are a couple of ways to reduce this knowledge transfer gap: * one should make the message concrete (avoid high level abstractions, at least initially) * Stories, too, work particularly well in dodging the curse of knowledge, because they force us to use concrete language. In an article titled [["Those Who Can Do, Can’t Teach"|https://www.nytimes.com/2018/08/25/opinion/sunday/college-professors-experts-advice.html]], Adam Grant who is an organizational psychologist, gives the following advice to students/learners, when picking a teacher/mentor/coach: * pay attention to how long it has been since a teacher studied the material. Instead of studying under people who have learned the most, it can be wise to study under people who have learned the most recently. * consider how difficult it was for the educator to master the material. We should be learning from overachievers: the people who accomplish the most with the least natural talent and opportunity. * focus as much on how well the teacher communicates the material as on how well the teacher knows the material. So Grant's advice: >Before you seek out an expert as your teacher or coach, remember that it’s not just about what they know; it’s about how recently and easily they learned it, and how clearly and enthusiastically they communicate it. On the other hand, Grant points out that the flip side of the saying [["Those Who Can Do, Can’t Teach"|https://www.nytimes.com/2018/08/25/opinion/sunday/college-professors-experts-advice.html]], namely the saying that “Those who can’t do, teach” is not necessarily true: ''Teachers often turn into great doers.'' After all, the best way to learn something is not to do it but to teach it. You understand it better after you explain it — and you remember it better after retrieving and sharing it. As you gain experience studying and explaining a skill, you might actually improve your ability to execute that skill.
Serendipity Alert! This is a case of "going down the rabbit hole" (actually, as you'll see momentarily, it __ends up__ being a hare :)
I came across an article (cleverly) titled [[Fox News|http://www.newyorker.com/magazine/2015/05/04/fox-news]] ("The truth about animal fables") in The New Yorker, about "What the stories of [[Reynard|http://fables.wikia.com/wiki/Reynard_the_Fox]] [an intelligent, talking fox] tell us about ourselves".
The article mentions Aesop's story about the //Tortoise and the Hare// and points out that the [[Penguin Classics edition|http://www.penguinclassics.co.uk/books/the-complete-fables/9780140446494/]] renders this beloved story in 5 sentences. Now that piqued my interest. Five sentences !
So, down the rabbit hole we go ...
!!!!The literary virtue of brevity
I was hooked. How can you condense the whole narrative and moral lesson of the Tortoise and the Hare into five sentences? I'm sure you remember the plot-line. From my childhood I don't remember it being a "swift" (ha!) story. Maybe because the publisher of the book of fables //we had at home// assumed it'd be a bed-time/story-time reading, and 5 sentences "just won't do" :)
Any (successful) condensing and distillation of wisdom intrigues me (hence my love of [[quotations|Quotes]]), so I was "compelled" to go down that rabbit hole...
Here is a //six line// translation by George Fyler Townsend (1867) (sorry for the 'rambling' version; I could not find the 'concise' one :)
>A hare one day ridiculed the short feet and slow pace of the Tortoise, who replied, laughing: 'Though you be swift as the wind, I will beat you in a race.'
>The Hare, believing her assertion to be simply impossible, assented to the proposal; and they agreed that the Fox should choose the course and fix the goal.
>On the day appointed for the race the two started together.
>The Tortoise never for a moment stopped, but went on with a slow but steady pace straight to the end of the course.
>The Hare, lying down by the wayside, fell fast asleep.
>At last waking up, and moving as fast as he could, he saw the Tortoise had reached the goal, and was comfortably dozing after her fatigue.
>//Slow but steady wins the race.//
!!!!The (proverbial) morality lesson(s)
The "beaten path" interpretations of the fable go something along (one or more of) the following lines:
* don't boast; don't be over-confident; don't brag; don't count your chickens before they hatch (or something similar)
* "the more haste, the worse speed"; "the race is not to the swift" (קֹהֶלֶת [[Ecclesiastes 9.11|http://www.mechon-mamre.org/p/pt/pt3109.htm]]; כִּי לֹא לַקַּלִּים הַמֵּרוֹץ)
* ingenuity/trickery/doggedness can pay off in overcoming a stronger/lazy/over-confident opponent (pick your noun-adjective pair)
* or even, "Action is the Business of Life, and there’s no Thought of ever coming to the End of our Journey in time, if we sleep by the Way." (by Sir Roger L'Estrange (1692))
* and, "many people have good natural abilities which are ruined by idleness; on the other hand, sobriety, zeal and perseverance can prevail over indolence."
and so on; all moral lessons we grew up with; some wiser and truer than others ...
!!!!The moral ambiguity
In most interpretations, the tortoise is the winner, both literally and morally, and the hare is the loser and fool.
But, we don't //really// know what exactly happened in that ancient race (and the fact that we have only 5 or 6 lines to go on, doesn't help in this case :).
Here is a distillation of a more [[modern interpretation of this story|http://www.fulltextarchive.com/page/Fifty-One-Tales/#p270]] by Lord Dunsany (Edward Plunkett) from 1915, where he claims to tell "The true history of the hare and the tortoise".
>[T]hey were off, and suddenly there was a hush.
>The Hare dashed off for about a hundred yards, then he looked round to see where his rival was.
>"It is rather absurd," he said, "to race with a Tortoise." And he sat down and scratched himself. [...]
>And after a while his rival drew near to him.
>"There comes that damned Tortoise," said the Hare, and he got up and ran as hard as could be so that he should not let the Tortoise beat him. [...]
>The Hare ran on for nearly three hundred yards, nearly in fact as far as the winning-post, when it suddenly struck him what a fool he looked running races with a Tortoise who was nowhere in sight, and he sat down again and scratched. [...]
>"Whatever is the use of it?" said the Hare, and this time he stopped for good. Some say he slept.
This version is interesting for 2 reasons:
* In this interpretation the hare is the thoughtful, logical, matter-of-fact beast. But in addition to Dunsany shedding a different light on the Hare (and the story), he also mocks the moral conclusions of the story, by ridiculing the cliches/bromides pronounced by the spectators of the race and "peppered" throughout the story, for example:
** "Run hard. Run hard," but also, at the same time "Let him rest."
** "Hard shell and hard living: that's what has done it."
** "It is a glorious victory for the forces of swiftness." (referring to the //tortoise//, mind you!)
And
* The second interesting twist is that drawing the wrong conclusions is not only ridiculous, but also dangerous. Dunsany continues:
>And the reason that this version of the race is not widely known is that very few of those that witnessed it survived the great forest-fire that happened shortly after. It came up over the weald by night with a great wind. The Hare and the Tortoise and a very few of the beasts saw it far off from a high bare hill that was at the edge of the trees, and they hurriedly called a meeting to decide what messenger they should send to warn the beasts in the forest.
>
>They sent the Tortoise.
It's fascinating how people take this story to different places, and draw different conclusions (and moral standards!) ...
[[Dunsany's version|http://www.fulltextarchive.com/page/Fifty-One-Tales/#p270]] can come across as a snobbish ridiculing of "the stupid common sense" of the masses. But I don't think that this is his point. I think that he is trying to point out to an important truth, and provide a much deeper wisdom, namely that "things are not always as they seem"; it is dangerous to apply (moral) standards blindly; bromides aren't always right; wisdom is not practiced by simplistically interpreting and applying formulas; context is important!
!!!!The paradox connection
And since we just mentioned going different places (or not :), here's a related (in a sense :) ''logical'' paradox (which can be solved with mathematical reasoning -- the [[convergence of a mathematical series of fractions|http://en.wikipedia.org/wiki/1/2_%2B_1/4_%2B_1/8_%2B_1/16_%2B_%E2%8B%AF]]).
You may have noticed that the Tortoise and Hare race in Aesop's classic Greek fable, echos another classic: [[Zeno's Paradox|http://en.wikipedia.org/wiki/Zeno%27s_paradoxes]], in which the Tortoise races Achilles. Zeno "reasons" that even though Achilles is faster, if the slower tortoise is given a lead (head start) the quicker runner can never overtake the slower, since the pursuer must first reach the point whence the pursued started, ad infinitum, and so the slower will always hold a lead.
In a very (Lewis) Carrollian way, the fable of the hare and the tortoise is an "explanation" of why "Zeno is right" ([[which he's not|http://www.slate.com/articles/health_and_science/science/2014/03/zeno_s_paradox_how_to_explain_the_solution_to_achilles_and_the_tortoise.html]]), and why the hare (or Achilles) will never (not even in wonderland :) catch up. They have a tough time -- now both math and/or morality are working against them...
More on Wonderland races in a moment (or two; depending on how fast (or slow) you read the computer program below :)
!!!!The Computer Science connection
This rabbit hole (shall we switch to hare?) leads even deeper (or wider). The story of the tortoise and the hare, has a useful application in computer science (I'm not making this up!): an algorithm implementing a "race", different "movement speeds"; in short, the whole chicken caboodle (or, turtle soup :)
This is an [[algorithm for Detecting a Loop in a Singly Linked List|http://codingfreak.blogspot.com/2012/09/detecting-loop-in-singly-linked-list_22.html]]. It was invented by Robert Floyd who called it "Tortoise and Hare".
The description of this algorithm is pretty simple. It starts like this:
>Let us take 2 pointers namely slow Pointer and fast Pointer to traverse a Singly Linked List at different speeds (see diagram below). A slow Pointer (Also called Tortoise) moves one step forward while fast Pointer (Also called Hare) moves 2 steps forward. And these are the steps of the algorithm:
>
>1. Start Tortoise and Hare at the first node of the List.
>2. If Hare reaches end of the List, return as there is no loop in the list.
>3. Else move Hare one step forward. (Hare needs to move at twice the speed of Tortoise - so this is an extra move)
>4. If Hare reaches end of the List, return as there is no loop in the list.
>5. Else move Hare and Tortoise one step forward. (Hare and Tortoise move 1 step. But because of step 3, Hare moves faster overall)
>6. If Hare and Tortoise are pointing to same Node, return; we found a loop in the list.
>7. Else go back to step 2.
>[img[Tortoise and Hare Algorithm|resources/single_linked_list_small.png][resources/single_linked_list.png]]
I have [[implemented a Python program|https://trinket.io/python/f172565c06]] (which you can run and modify in the browser) to demonstrate how it works:
<html>
<table style="border:none;">
<tr style="border:none;">
<td style="border:none;">
<pre>
# An algorithm for Detecting a Loop in a Singly Linked List.
# Invented by Robert Floyd who called it "Tortoise and Hare".
# Implemented by hmark.
# The Singly Linked List is implemented as a list of nodes.
# Each node in the list is itself a 2-element list, where
# the first element is the number of the node, and
# the second element is the number of the node it points to.
# in looped_list, node 0 points to node 1, and so on, until node 6 points to node 3
# thus creating a loop, where the end node 7 is "detached" from the list.
looped_list = [ [0,1], [1,2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 3], [7, 8] ]
# in straight_list, node 0 points to node 1, and so on, all the way to the last node (7)
# thus creating a straight linked list with no loops.
straight_list = [ [0,1], [1,2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8] ]
def is_loopy(path):
tortoise = path[0] # slow pointer, starts at the beginning of the list
hare = path[0] # fast pointer, also starts at the beginning of the list
end = path[-1] # point to the last node
while True:
if hare == end:
return False
hare = path[hare[1]] # move the fast pointer to the next node
if hare == end:
return False
hare = path[hare[1]] # move the fast pointer to gain twice the speed
tortoise = path[tortoise[1]] # move the slow pointer to the next node
if hare == tortoise:
return True
print looped_list
print is_loopy(looped_list)
print
print straight_list
print is_loopy(straight_list)</pre>
</td>
</tr>
</table>
</html>
!!!!The return to Alice in Wonderland
All good things lead to //Alice in Wonderland//, or to //Through the Looking Glass// (or they just come to an end :)
As you may know, Lewis Carroll has multiple "ridiculous races" in these stories.
__The first one__ (and running through Wonderland) is the one where Alice chases after the rabbit down the rabbit hole:
>burning with curiosity, [Alice] ran across the field after [the rabbit], and fortunately was just in time to see it pop down a large rabbit-hole under the hedge.
>In another moment down went Alice after it, never once considering how in the world she was to get out again.
As Alice was falling down the rabbit hole, she wasn't so sure for how long she was falling, or when it will end, if ever:
>Down, down, down. Would the fall never come to an end? 'I wonder how many miles I've fallen by this time?' she said aloud.
But isn't it the same with "trains of thought" and "flights of fancy"? You never know where you'll end up (and the piece you are reading now is a proof of that :)
As an aside: if you think about it, an object falling through a __straight line tunnel__ connecting two points on the surface of the earth would oscillate back and forth between these points and will not stop (if we ignore friction and the [[Coriolis effect|http://en.wikipedia.org/wiki/Coriolis_effect]] due to Earth's rotation). Thankfully, our reflections and associations can be (and will be :) stopped.
But, regardless of the physics, Carroll makes the rabbit fast enough and non-oscillating, and for a while it doesn't look like Alice will be able to catch up, since //this// rabbit is too nervous and stressed out to take a nap ...
__Second, there is the caucus race__ (//Alice in Wonderland//, chapter 3: Caucus Race and a Long Tale):
> 'What is a Caucus-race?' said Alice; not that she wanted much to know, but the Dodo had paused as if it thought that somebody ought to speak, and no one else seemed inclined to say anything.
>'Why,' said the Dodo, 'the best way to explain it is to do it.' (And, as you might like to try the thing yourself, some winter day, I will tell you how the Dodo managed it.)
>
>First it marked out a race-course, in a sort of circle, ('the exact shape doesn't matter,' it said,) and then all the party were placed along the course, here and there. There was no 'One, two, three, and away,' but they began running when they liked, and left off when they liked, so that it was not easy to know when the race was over. However, when they had been running half an hour or so, and were quite dry again, the Dodo suddenly called out 'The race is over!' and they all crowded round it, panting, and asking, 'But who has won?'
>This question the Dodo could not answer without a great deal of thought, and it sat for a long time with one finger pressed upon its forehead (the position in which you usually see Shakespeare, in the pictures of him), while the rest waited in silence. At last the Dodo said, 'Everybody has won, and all must have prizes.'
__And there is the running in place__ of Alice and the Red Queen (//Through the Looking Glass//, chapter 2: The Garden of Live Flowers):
>Just at this moment, somehow or other, they began to run. Alice never could quite make out, in thinking it over afterwards, how it was that they began: all she remembers is, that they were running hand in hand, and the Queen went so fast that it was all she could do to keep up with her: and still the Queen kept crying 'Faster! Faster!' but Alice felt she //could not// go faster, though she had not breath left to say so.
>The most curious part of the thing was, that the trees and the other things round them never changed their places at all: however fast they went, they never seemed to pass anything. 'I wonder if all the things move along with us?' thought poor puzzled Alice. And the Queen seemed to guess her thoughts, for she cried, 'Faster! Don't try to talk!'
>
>Not that Alice had any idea of doing //that//. She felt as if she would never be able to talk again, she was getting so much out of breath: and still the Queen cried 'Faster! Faster!' and dragged her along. 'Are we nearly there?' Alice managed to pant out at last.
>'Nearly there!' the Queen repeated. 'Why, we passed it ten minutes ago! Faster!' And they ran on for a time in silence, with the wind whistling in Alice's ears, and almost blowing her hair off her head, she fancied.
>'Now! Now!' cried the Queen. 'Faster! Faster!' And they went so fast that at last they seemed to skim through the air, hardly touching the ground with their feet, till suddenly, just as Alice was getting quite exhausted, they stopped, and she found herself sitting on the ground, breathless and giddy.
>
>The Queen propped her up against a tree, and said kindly, 'You may rest a little now.'
>Alice looked round her in great surprise. 'Why, I do believe we've been under this tree the whole time! Everything's just as it was!'
>'Of course it is,' said the Queen, 'what would you have it?'
>'Well, in //our// country,' said Alice, still panting a little, 'you'd generally get to somewhere else -- if you ran very fast for a long time, as we've been doing.'
>'A slow sort of country!' said the Queen. 'Now, //here//, you see, it takes all the running //you// can do, to keep in the same place. If you want to get somewhere else, you must run at least twice as fast as that!'
>'I'd rather not try, please!' said Alice. 'I'm quite content to stay here -- only I //am// so hot and thirsty!'
__And then there are Alice and the White King__ hurrying to see the Lion and the Unicorn fighting (//Through the Looking Glass//, chapter 7: The Lion and the Unicorn):
>[The White King said:]'Let's run and see them.' And they trotted off, Alice repeating to herself, as she ran, the words of the old song:
>> The Lion and the Unicorn were fighting for the crown:
>> The Lion beat the Unicorn all round the town.
>> Some gave them white bread, some gave them brown;
>> Some gave them plum-cake and drummed them out of town.'
>
>'Does -- the one -- that wins -- get the crown?' she asked, as well as she could, for the run was putting her quite out of breath.
>'Dear me, no!' said the King. 'What an idea!'
>'Would you -- be good enough,' Alice panted out, after running a little further, 'to stop a minute -- just to get -- one's breath again?'
>'I'm //good// enough,' the King said, 'only I'm not strong enough. You see, a minute goes by so fearfully quick. You might as well try to stop a [[Bandersnatch|http://en.wikipedia.org/wiki/Bandersnatch]]!'
>Alice had no more breath for talking, so they trotted on in silence, till they came in sight of a great crowd, in the middle of which the Lion and Unicorn were fighting.
the silly merriment continues, but we will stop here, and follow the (sage) advice the King of Hearts gives the rabbit (//Alice in Wonderland//, chapter 12: Alice's Evidence):
>Read [the accusing verses],' said the King [to the rabbit].
>The White Rabbit put on his spectacles. 'Where shall I begin, please your Majesty?' he asked.
>'Begin at the beginning,' the King said gravely, 'and go on till you come to the end: then stop.'
So we do. We did. We are done.
(And as promised at the beginning of this piece, ''it'' does ''end'' with a rabbit. (and the (only?) open question is what //it// refers to :))
An intellect which at a given instant knew all the forces acting in nature, and the position of all things of which the world consists-supposing the said intellect were vast enough to subject these data to analysis-would embrace in the same formula the motions of the greatest bodies in the universe and those of the slightest atoms; nothing would be uncertain for it, and the future, like the past, would be present to its eyes. This view is reflected in Tom Stoppard's play Arcadia (analyzed very well in [[“It’s wanting to know that makes us matter”: Epistemological and Dramatic Issues in Tom Stoppard’s Arcadia, by John Fleming|https://journals.openedition.org/miranda/5551?lang=en]] ([[GD copy|https://docs.google.com/document/d/1CvYPIUwXPDHEDWxL06ApmPbjB-4c40poo4mfg5tfu5Q/edit?usp=sharing]]), where: >Thomasina [a talented, precocious 13-year-old pupil] explains the ramifications of what would happen if everything behaved according to Newton’s laws of motion: “If you could stop every atom in its position and direction, and if your mind could comprehend all the actions thus suspended, then if you were really, really good at algebra you could write the formula for all the future; and although nobody can be so clever to do it, the formula must exist just as if one could.” But, to Stoppard's (and Thomasina's) credit: >Thomasina has already begun to intuit that this view of the universe is incomplete. She tells her tutor: “When you stir your rice pudding, Septimus, the spoonful of jam spreads itself round making red trails like the picture of a meteor in my astronomical atlas. But if you stir backward, the jam will not come together again.” [AKA the second law of thermodynamics].
Public perception of artificial intelligence (AI) ^^1^^
<a href="./resources/chess_game.jpeg" target="new"><img src="./resources/chess_game.jpeg" width="75%" height="75%" /></a>
"I remember when you could only lose a chess game to a supercomputer."^^1^^ - New Yorker Cartoon, by: Avi Steinberg
Sometimes a work of science fiction tells more about the time of its creation then it does the future it purports to predict. In the Stanley Kubrick/Arthur C. Clarke 1968 epic film 2001: A Space Odyssey, about the central character -- the HAL 9000 computer -- [[talks amiably|HAL 9000 chatbot - educational multimedia design principles]], renders aesthetic judgments of drawings, recognizes the emotions in the crew, but also murders four of the five astronauts in a fit of paranoia and concern for the mission. At the time of the filming -- before anyone had a Ph.D. in computer science, before the PC and Macintosh, before duogenarians started buying Ferraris from the IPOs of their software companies -- the general public knew little about computers and had virtually no direct experience with them. As such, the film's compelling and carefully considered representation of HAL and his abilities embodied almost as much hope and fear as it did knowledge and analysis.
Shortly after we meet HAL, he plays chess against astronaut Frank Poole, and this scene tells us a great deal about computers and 1960s society's view toward them. First, it is significant what is not shown. Kubrick originally filmed the scene with Dave playing a new game, "Pentominoes," then being promoted by the Milton-Bradley Game Corporation. Kubrick rejected this because although Pentominoes might have gone on to popularity, film goers wouldn't quite know what the astronaut was doing (programming or controlling some aspect of the ship perhaps?). Even if they did recognize it as a game, viewers wouldn't know just how difficult it was and thus how impressive HAL's inevitable win would be. Kubrick chose chess in large part to show how "intelligent" HAL was; chess has long been held as a paradigm of the heights of human logic and reasoning. (It should be pointed out that Kubrick is an avid chess player and as a teenager hustled chess in the parks of Brooklyn during the 1950s. Moreover, in the novel 2001, HAL is programmed to lose 50% of the time to keep things interesting for the astronauts.)
Next, consider the particular sequence of moves Kubrick shows. These are moves 13 through 15 from an obscure game between two German masters played in Hamburg in 1913 (the Ruy Lopez or Spanish opening). We can presume that Kubrick chose this set of moves because of the cleverness of the checkmate clever enough that an astronaut might not see it, yet short and easy enough for chess-literate viewers to recognize and admire.
Recall, too, Frank's reaction to his loss -- or more specifically his lack of reaction. He clearly accepts defeat without anguish. His pause is brief and he doesn't even take time to confirm the mate carefully -- he knows HAL is correct in his announcement of the checkmate. But Frank's lack of reaction is very significant. Although it may seem a bit quaint in the late 1990s, at the time of the filming of 2001, in the public's mind there was a clear pro-human/anti-computer sentiment, at least as far as chess was concerned. Even in the human-machine tournaments in the '70s and early '80s, audiences rooted for the human and against the machine. Nowadays, few of us feel deeply threatened by a computer beating a world chess champion -- any more than we do at a motorcycle beating an Olympic sprinter [Haggai: or [[Dijkstra's 'swimming' submarine|The question of whether a computer can think is no more interesting than the question of whether a submarine can swim.]] ]. It is true, chess masters will be the most distraught (Kasparov has called his last tournament "species defining"), and true, it will garner great public interest. Nevertheless, among scientists working in the field it may be important, but for other reasons I'll explain below.
In short, in 2001 Kubrick and Clarke were absolutely right to predict that
:: - we would play games with computers for diversion (this was not obvious in the 1960s, incidentally, before Pong, Nintendo and Sega Genesis)
:: - computers would become superb chess players, surely able to beat an astronaut.
Let me digress and take the Kasparov/Deep Blue rematch as a good chance to dispel a myth that has grown up around 2001. The story has it that the name HAL was chosen because each letter is just one step ahead of IBM. However, this is pure coincidence, and in fact the first incarnations of the computer had a woman's voice and was called "Athena," goddess of wisdom. When someone pointed out the spurious association between HAL and IBM, Kubrick wanted to change the computer's name and refilm the scenes but was dissuaded because of production costs. (For the record, HAL comes from "Heuristically programmed Algorithmic" computer.)
But back to HAL: Yes, HAL was brilliant and amiable but, at least in the public's mind, capable of evil. His triumph over Frank in chess presages the murder in outer space. HAL surely was "intelligent," and his prowess at chess helps to convince us of that.
But how do we "measure" or test his intelligence?
!!!The chess Turing test
(compare with [[Brian Christian's experience|The Most Human Human - by Brian Christian]] participating in the annual [[Turing Test|https://plato.stanford.edu/entries/turing-test/]] Event in England).
The question "Is a machine intelligent?" is a notoriously difficult one and thus in 1950 the computer science pioneer Alan Turing proposed his famous test: There are two keyboards in front of you, one connected to a computer, the other leads to a person. You type in questions on any topic you like; both the computer and the human type back responses that you read on the respective computer screens. If you cannot reliably determine which was the person and which the machine, then we say the machine has passed the Turing test. HAL, of course, passed with flying colors. No computer can pass such an unrestricted Turing test today or will for quite some time. For this reason, we restrict the test, to give the computer a fighting chance.
One such restricted test is a chess Turing test: You play chess against an opponent whose moves are presented by means of a computer screen, and you try to determine whether your opponent is a computer or a human. Chess Turing tests have been conducted, but with a slight twist. You get to see only the recorded moves of a previous game and must state if either opponent -- or possibly both or possibly neither -- was a computer. This is a just a bit tougher than a true chess Turing test because now you're seeing a game played by others, one where the opponents were trying to win. Consider: If you were playing and your goal was to determine whether the opponent is a computer, you might be clever and lose the game in a particularly interesting way that might reveal the identity of your opponent.
In such modified chess Turing tests (based on recorded games), just as in the original Turing test, the better the computer, the harder it is to distinguish between human and machine opponents. In an informal experiment, Kasparov could occasionally, but not reliably, guess from recorded games whether opponents were human or machine. We now know that we can make computers excel on limited problems, such as chess, or controlling an oil refinery, or even complicated medical diagnoses, but we are very far indeed from creating a computer to pass an unrestricted Turing test. But more on that below.
!!!Should we mimic humans to achieve AI?
Should we try to make artificial intelligence by duplicating how humans do it, or instead try to exploit the particular strengths of machines? Humans are slow but exquisitely good at pattern recognition and strategy; computers, on the other hand, are extremely fast and have superb memories but are annoyingly poor at pattern recognition and complex strategy. Kasparov can make roughly two moves per second; Deep Blue has special-purpose hardware that enables it to calculate nearly a quarter of a billion chess positions per second.
Here is an illustration of the difference, taken from chess: Controlled psychological experiments have shown that human chess masters are far more accurate than non-chess players at remembering chess board positions taken from real games, where the placement of pieces arose in strategic play and represented meaningful tactical positions. However, these masters were no better than non-chess players at memorizing random arrangements of pieces. Chess masters remember positions based on certain patterns, alignments and structure whereas, of course, computers have no difficulty remembering -- storing -- all the games or random arrangements ever made and need no "meaning" in the placements.
There are other differences too, of course. Humans have emotions - they have pride at winning, shame at a bad loss, satisfaction when extracting revenge; not so computers (well, not yet). Computers don't get tired, and don't have "bad" days -- at least so long as the hardware doesn't break down!
Early chess systems sought to duplicate or mimic the methods of humans. But this proved to be far too difficult: What precisely suggests any particular move? Instead, successful chess programs capitalize on the particular strengths of computers: rapid and massive parallel search. This is quantified by how many moves ahead, or "plies," the computer can search in a given time. If I move, that's one ply; if you then also move, that's two plies, and so forth. Naturally, the deeper the computer can search, the stronger a player it is. The interesting thing about computer chess is the extremely good correlation between the average depth of search (measured in plies) and the strength in chess, quantified by the rating.
Humans have an uncanny ability to see or "sniff out" sequences of moves that are likely to pay off down the line -- an example of sophisticated pattern recognition -- for instance, as if to say "Gosh, I'm not sure why, but I think that attacking his king's knight's pawn with my queen's bishop looks promising... let me explore that line of attack..." As such, human grandmasters don't waste time on unpromising sequences but tend to look far down the promising avenues and see traps beyond the search "horizon" of a brute force machine search. This, in fact, is one of the strategies employed by grandmasters, including Kasparov, when playing against computers. Well it turns out that for the 1913 Hamburg game used in the scene in 2001, the earliest moves (which would have occurred before the film's scene) were indeed quite "trappy" in this way, and assuming HAL played them, we would say that he would pass the chess Turing test - not surprising, since the game was actually from a human match.
Another difference between human and computer chess play involves learning or adaptability. Machines play the same way again and again, and given a particular setup will always play the same move. During a game, however, a human grandmaster might notice that his opponent is aggressive or conservative or risky or trappy, and change his own style of play accordingly. Humans even do this from game to game in a tournament against a single opponent. Garry Kasparov stated quite clearly that his tournament victory over Deep Blue in February 1996 came because he could analyze the first game and play to exploit Deep Blue's evident weaknesses in the next. Conversely, Kasparov changed his own style of play in the middle of games, and Deep Blue was not prepared to adapt accordingly.
The ability of computers to do extensive search has had ramifications on endgame play, where only a few pieces are left on the board, such as a king, bishop and knight versus a king and a pawn. Certain endgame arrangements were always thought to represent a draw -- no human had ever seen a way to win. Nevertheless, through deep -- very deep -- computer searches, some of these positions were proven to be a forced win. In one setup, a Connection Machine supercomputer found a forced checkmate in an astounding 249 moves! There is a scientific paper on the subject in the original German, which said playing against a computer programmed with these endgame sequences was "Schachspielen wie gegen Gott"-- chess playing as if against God. Garry Kasparov himself said it best: "Sometimes quantity becomes quality."
Once some of these endgames were shown to be wins, a few tournament players tried to memorize the necessary sequence of moves. This leads to a fascinating point: Whereas researchers began by trying to make computer chess systems imitate the style of humans, paradoxically it turns out that some humans play their endgames by imitating computers! Thus, at least in some aspects of endgame play, machines are clearly superior to humans.
It turns out that the Japanese board game "go" will not succumb to such brute force methods -- there are simply too many possible moves for even the most powerful supercomputer imagined to ever examine. Instead, "real" AI will be needed -- intelligence based on pattern recognition, "insight" and strategy. Indeed, for those of us who work in pattern recognition, machine learning, or various fields allied with artificial intelligence, it is the weaknesses of Deep Blue that are the most interesting. How should we program computers to recognize and understand the style of their opponent's play and adapt accordingly? How should we program the machine to distinguish the most promising lines of attack from the ones that are not likely to pay off? How do we program machines to make complex plans? Whereas there are some aspects of the Deep Blue system that employ crude versions of methods we know are important in human intelligence (in particular when scoring the quality of a position), their weaknesses are compensated by the brute force search through possible moves.
It must be emphasized, too, that even if such subtle and complicated techniques of pattern recognition, reasoning and so forth are ultimately achieved in chess, there would still remain an enormous gulf between their use in chess and in other general aspects of intelligence, for instance, in planning a story or recognizing a scene. For these, we may have to duplicate the human, at least at some level of abstraction.
!!!A new era?
I am assuming that computers will ultimately triumph over humans in the domain of chess, if not at this Deep Blue/Kasparov tournament, then in the not-too-distant future.^^2^^ True, technologists tend to be optimists, and the predictions of a number of computer scientists vis-a-vis chess -- from Alan Turing to Marvin Minsky to Raymond Kurzweil -- have been overly optimistic. Furthermore, humans will continue to improve surely Kasparov is improving, in part from his competition with computers. Nevertheless the trends are clear enough, and although I will not hazard a guess as to when it will occur, I am confident that someday a computer will reign supreme in chess.
It has been said that when computers become world champions, we will either:
- think more of computers
- think less of humans or
- think less of the game of chess.
My view is that we will think just a bit more of computers (at least for these and related problems) and still admire the game of chess. I think we will -- or at least we should -- think more of humans, not less. We will appreciate just how difficult problems like pattern recognition and planning and creativity are, and how poorly scientists and technologists have done in trying to reproduce these human behaviors.
The public should understand one of the central lessons of the last 40 years in AI research: that problems we thought were hard turned out to be fairly easy, and that problems we thought were easy have turned out to be profoundly difficult. Chess is far easier than innumerable tasks performed by an infant, such as understanding a simple story, recognizing objects and their relationships, understanding speech, and so forth. For these and nearly all realistic AI problems, the brute force methods in Deep Blue are hopelessly inadequate.
With the (presumed) forthcoming "solution" to the chess problem, I think we will come to the end of an era the era of the "quick kill" where hardware and brute force solve interesting problems. Chess is the last problem in traditional AI that will garner great public attention and be solvable by "simple" brute force techniques. Natural language understanding, scene analysis, speech recognition, and much more will require much more work and work of a different sort, than that used for chess. We'll be at the end of one road that leads just part of the way through the forest.
Thus we are led to ask, after chess, "whither AI"?
I think there will be a sober reconsideration and broad acceptance of the magnitude of the AI problem, and a realization that the techniques that proved successful in chess will be of only limited use in the domains where humans currently dominate and which we view as essential for AI. In addition to continued research progress, what happens then will depend in part upon whether scientists and engineers can make a coherent case that we know enough about the foundations of AI and that we are in a position for larger scale projects. What might the research projects be like?
Doug Lenat's CYC project -- a several-decades-long knowledge engineering mission for entering common sense and general knowledge into machines -- may give the flavor of the future. Although it is too early to judge the eventual success or failure of his particular system, which is still years from coming fully on-line, we can note some of its attributes that presage things to come. First, his system addresses general intelligence, rather than just a specific domain such as chess. For example, his system could be used for interpreting handwriting (by providing knowledge of reasonable alternative readings of ambiguous words) or searching labeled images (by inferring related terms and concepts that are not in a thesaurus) or spotting inconsistencies in a database. Second, Lenat's program isn't concerned with proving arcane theorems that may be of limited use, but instead relies on lots of repetitive (and I would imagine boring) knowledge engineering -- the digital age's answer to sweat shops. Third, it acknowledges the magnitude of the problem -- it already embodies over a person-century of data entry during the last dozen years, and still has much to do.
The CYC project, as large as it may be, is still peanuts on the scale of big science in other disciplines. The physicists have their multibillion-dollar particle accelerators, the astronomers their space missions, and microbiologists their human genome project, but there is no equivalent in computer science and AI, at least not in the U.S. We can imagine enormous software projects for learning simple objects or animal shapes, which would be useful in searching the World-Wide Web, and work on integrating and mediating large numbers of experts on subproblems.
!!!Conclusion
The problems addressed by AI are some of the most profound in all of science: How we know the world? What is the "essence" of an object or pattern? How do we remember the past? How do we create new ideas? For centuries, mankind had noticed hearts in slaughtered animals; nevertheless, the heart's true function was a mystery until one could liken it to an artifact and conclude: a heart is like a pump. (Similarly, an eye is like a camera obscura, a nerve is like an electric wire....) In the same way, we have known for centuries the brain that is responsible for thoughts and feelings, but we'll only truly understand the brain when our psychological and neurological knowledge is complemented by an artifact -- a computer that behaves like a brain. As such, AI is in the long tradition of philosophy and epistemology; it is surely worthy of our support as a culture. (It also will have immense practical benefits.)
We should take the eventual triumph of machines in chess as a milestone -- the end of the easy era. It should also mark a new era, one where researchers eliminate the hype and false promises, epitomized by the prediction of a HAL. We will deepen our admiration for the problem -- and buckle down for some real hard work.
----
^^1^^ - On the other hand...
[img[Kasparov beats deep blue|resources/Kasparov beats Deep Blue.png]]
^^2^^ As we all know, IBM's Deep Blue eventually defeated Gary Kasparov in 1997. Later, in 2017, Google's Alpha Go AI [[defeated the Go world champion|https://www.theatlantic.com/technology/archive/2017/10/alphago-zero-the-ai-that-taught-itself-go/543450/]]. But as a wise man said after that defeat:
> The mounted horse did not kill athletics. We run for joy.
and he was right of course.
!!!!References
HAL's Legacy: 2001's computer as dream and reality, edited by David G. Stork, Foreword by Arthur C. Clarke, MIT Press (1997)
Letter to the Editor on computer chess by David G. Stork, Scientific American, p. 10 (March 1991). Kasparov vs. Deep Blue: Computer Chess Comes of Age by Monroe Newborn, Springer-Verlag (1996) A New Era: World Championship Chess in the Age of Deep Blue by Michael Khodakovsky, Ballentine (1997)
This piece is based in part on my illustrated lecture "The HAL 9000 computer and the vision of '2001: A Space Odyssey'," and Murray Campbell's chapter in HAL's Legacy: 2001's computer as dream and reality (MIT Press, 1997); his insights are gratefully acknowledged. You can read his and other full chapters on-line by clicking on the link to the book. You can see other events associated with the birth of the HAL 9000 computer here.
David G. Stork is Chief Scientist of Ricoh Silicon Valley, as well as Consulting Associate Professor of Electrical Engineering and Visiting Scholar in Psychology at Stanford University. He has had a lifelong interest in chess, and competed twice in the United States High School Chess Championships in the 1970s (he no longer plays competitively). His five books include HAL's Legacy: 2001's computer as dream and reality (MIT Press) and the forthcoming Pattern Classification (2nd ed.) (Wiley).
I recently came across [[an interesting blog entry|http://blog.mrmeyer.com/?cat=51]] by [[Dan Meyer|http://blog.mrmeyer.com/]] about the fit of computers to Math education and the point that Silicon Valley is missing the point, trying to fit the tool (computers) to the challenge (teaching/learning math). Meyer (who had been a math teacher, and IMO comes at it the right way, and has a very original and effective way to teach math) says: >Do you want to know where this post became useless to Silicon Valley's entrepreneurs, venture capitalists, and big thinkers? Right where I said, "Computers are not a natural working medium for mathematics." They understand computers and they understand how to turn computers into money so they are understandably interested in problems whose solutions require computers. Sometimes a problem comes along that doesn't naturally require computers. Like mathematics. They may then define, change, and distort the definition of the problem until it does require computers. To which Jesse Farmer [[responds|http://news.ycombinator.com/item?id=3563402]]: >In design, a skeuomorph is a derivative object that retains some feature of the original object which is no longer necessary. For example, iCal in OS X Lion looks like a physical calendar, even though there's no reason for a digital calendar to look (or behave) like a physical calendar. The same goes for the address book. >This is what I see happening in online education. I don't think it's a case of "lol, Silicon Valley only trusts computers," but rather starting off by doing the most literal thing. Textbooks? Let's publish some PDFs online. Lectures? Let's publish videos online. Homework and tests? Let's make a website that works like a multiple-choice or fill-in-the-blank test. These are skeumorphs. There's no reason for the online equivalent of a textbook to be a PDF, it's just the most obvious thing. >For me it's 1000x more interesting to ask "On the web, what's the best way to do what a lecture does offline?" than to say "Khan Academy videos are the wrong way of doing it."^^1^^ >I think sites like Codecademy point the way when it comes to programming. The textbook is the IDE. >What does that look like for math? It's much harder because, like Dan says, computers aren't the natural medium for mathematicians, so there will always be a translation step from math-ese to computer-ese. >Once you're past basic math and are working out of a higher-level textbook, the exercises becomes very awkward to express on a computer in a way a computer can understand. I agree with Dan that math is not necessarily "a natural" for computers, and when looking at current/common computer-based/assisted/aided/mediated math teaching/learning systems/environments, it definitely feels like "old wine (or is it vinegar?) is 'shoehorned' into new bottles" (sorry for the mixed metaphor), which is jfarmer's point. He is probably correctly pointing out that it's easy/natural to try to keep doing the same/similar thing in a new medium or environment, but I also think that there is another, deeper reason for continuing to "teach the new dogs the old tricks" (and I apologize to all learners, but it sometimes really feels like we treat them Pavlovianly). And I think the reason has to do with the strong/ingrained belief that math (in this case) has to be taught/learned from the ground up: first comes "the language", with basic concepts, etc., followed by more advanced ideas and techniques which build on that foundation, and so on. Mathematicians and lecturers like Lockheart already [[lamented this|A case for "loosening up a bit"]], and visionary leaders and lectures like Gershenfeld are trying to address this (through [[interdisciplinary learning/curricula|Interdisciplinary Learning]]). But in my mind, if we break away from this "bottom-up" curriculum, computers can become the "ways and means" and very powerful allies. It's interesting that Dan Meyer is using technology (not necessarily computers) in his [[3 act math lessons|https://docs.google.com/spreadsheet/ccc?key=0AjIqyKM9d7ZYdEhtR3BJMmdBWnM2YWxWYVM1UWowTEE]] in a way that I would definitely not characterize as bottom-up. As Meyer says about [[his 3 acts|http://blog.mrmeyer.com/?cat=95]]: >I aspire to be perplexing. I want to perplex my students, to put them in a position to wonder a question so intensely they'll commit to the hard work of getting an answer, whether that's through modeling, experimenting, reading, taking notes, or listening to an explanation. >A lot of my most perplexing classroom moments have had two elements in common: > * A visual. A picture or a (short) video. > * A concise question. One that feels natural. One that people can approach first on a gut level, using their intuition. >Let's call that a first act. There are still two more acts and a lot of work yet to do, but the first act is above and before everything else. ([[more about Dan Meyer's 3 acts|The Three Acts Of A Mathematical Story]]) And this is the crux of it! You don't start engaging the learner at the bottom; you "jump right into the middle", and then you go up or down as you need to. This is powerful learning! And computers with their visualization, modeling, search, simulation, and number crunching, fast response/feedback, are a "great empowerer". There is another, and in my mind not less powerful and engaging approach compared to "start in the middle, and go up or down, as you need to" (see above), which is the approach of "sometimes it's easier to start with the ''theoretical analysis'', and sometimes it's easier to start with a ''computer simulation'' (or [[Computer Simulation vs. Theoretical Analysis]]). Both are valid, powerful, knowledge acquisition approaches. ---------------------- ^^1^^ See [[the value of the Khan Academy videos|The Khan Academy]]
As opposed to the Drake Equation (see [[Interdisciplinary knowledge in an equation]] and also [[Frank Wilczek on Intelligent Life in the universe]] :) From [[xkcd|https://xkcd.com/718/]]: [img[The Flake Equation|resources/Flake Equation small.png][resources/Flake Equation.png]] and Michael Shermer's [[equation analysis|https://michaelshermer.com/2011/10/the-flake-equation/]] at The Skeptic Magazine.
From Pete Goodliffe's book //Becoming a Better Programmer//: You can learn falsehood and believe that it’s right. This can be at best embarrassing, and at worst dangerous. This is illustrated by the Four Stages of Competence (a classification posited in the by 1940s by psychologist Abraham Maslow). You may have: ''Unconscious incompetence'' This is a dangerous place to be. You don’t know that you don’t know something. You are ignorant of your ignorance. Indeed, it is very possible that you think you understand the subject but don’t appreciate how very wrong you are. It is a blind spot in your knowledge. ''Conscious incompetence'' You don’t know something. But you know that you’re ignorant. This is a relatively safe position to be in. You probably don’t care—it’s not something you need to know. Or you know that you’re ignorant and it is a source of frustration. ''Conscious competence'' This is also a good state to be in. You know something. And you know that you know it. To use this skill you have to make a conscious effort, and concentrate. ''Unconscious competence'' This is when your knowledge of a topic is so great that it has become second nature. You are no longer aware that you are using your expertise. Most adults, for example, can consider walking and balance as an unconscious competence—we just do it without a second thought.
[[Alan Kay|https://en.wikipedia.org/wiki/Alan_Kay]] (a "[[CS Sage|https://en.wikipedia.org/wiki/List_of_computer_scientists]]") in his article [[The Future of Reading Depends on the Future of Learning Difficult to Learn Things|http://www.vpri.org/pdf/future_of_reading.pdf]] on human ability amplifiers, and specifically reading (as opposed to memorizing): >Socrates’ complaints about writing included “Writing removes the need to remember”. He meant that a prosthetic brace on a healthy limb will induce withering. On the other hand, if we think of new technologies as amplifiers that add or multiply to what we already have rather than replacing them—then we have the opportunity to use writing for its reach over time and space, its efficiencies, and its ability to hold forms of argument that don’t work in oral discourse. And we can still learn to remember all we’ve read! In other words, writing is not a good replacement for memories used in thinking—too inefficient—but is a great way to cover more ground, to cover different ground, and to have more to think about and with. See also [[A Helpful Guide to Reading Better - Farnam Street]].
Melanie Mitchell is echoing Andrea diSessa's thoughts on [[the power of a new language or literacy|The power of a new literacy]] to significantly enhance our ways of thinking and dealing with the world: >...we don't have the right vocabulary to precisely describe what we re studying [the science of complexity]. We use words such as complexity, self-organization, and emergence to represent phenomena common to the systems in which we re interested but we can t yet characterize the commonalities in a more rigorous way. We need a new vocabulary that not only captures the conceptual building blocks of self-organization and emergence but that can also describe how these come to encompass what we call functionality, purpose, or meaning. These ill-defined terms need to be replaced by new, better-defined terms that reflect increased understanding of the phenomena in question. As I have illustrated in this book, much work in complex systems involves the integration of concepts from dynamics, information, computation, and evolution. A new conceptual vocabulary and a new kind of mathematics will have to be forged from this integration. The mathematician Steven Strogatz puts it this way: I think we may be missing the conceptual equivalent of calculus, a way of seeing the consequences of myriad interactions that define a complex system. It could be that this ultracalculus, if it were handed to us, would be forever beyond human comprehension. We just don't know. >Having the right conceptual vocabulary and the right mathematics is essential for being able to understand, predict, and in some cases, direct or control self-organizing systems with emergent properties. Developing such concepts and mathematical tools has been, and remains, the greatest challenge facing the sciences of complex systems. >[...] >Accomplishing all of this will require something more like a modern Isaac Newton than a modern Carnot. Before the invention of calculus, Newton faced a conceptual problem similar to what we face today. In his biography of Newton, the science writer James Gleick describes it thus: He was hampered by the chaos of language words still vaguely defined and words not quite existing. . . . Newton believed he could marshal a complete science of motion, if only he could find the appropriate lexicon.. . . By inventing calculus, Newton finally created this lexicon. Calculus provides a mathematical language to rigorously describe change and motion, in terms of such notions as infinitesimal, derivative, integral, and limit. These concepts already existed in mathematics but in a fragmented way; Newton was able to see how they are related and to construct a coherent edifice that unified them and made them completely general. This edifice is what allowed Newton to create the science of dynamics. >Can we similarly invent the calculus of complexity a mathematical language that captures the origins and dynamics of self-organization, emergent behavior, and adaptation in complex systems? There are some people who have embarked on this monumental task. For example, as I described in chapter 10, Stephen Wolfram is using the building blocks of dynamics and computation in cellular automata to create what he thinks is a new, fundamental theory of nature. As I noted above, Ilya Prigogine and his followers have attempted to identify the building blocks and build a theory of complexity in terms of a small list of physical concepts. The physicist Per Bak introduced the notion of self-organized criticality, based on concepts from dynamical systems theory and phase transitions, which he presented as a general theory of self organization and emergence. The physicist Jim Crutchfield has proposed a theory of computational mechanics, which integrates ideas from dynamical systems, computation theory, and the theory of statistical inference to explain the emergence and structure of complex and adaptive behavior. In an article titled [[ASYMPTOTIC BEHAVIOUR AND RATIOS OF COMPLEXITY IN CELLULAR AUTOMATA|https://arxiv.org/pdf/1304.2816.pdf]] Hector Zenil and Elena ~Villareal-Zapata analyze the sensitivity of (even simple) [[1D (or Elementary) Cellular Automata|http://mathworld.wolfram.com/ElementaryCellularAutomaton.html]] to changes in initial conditions. 1D CA are important since they may [[shed some light of complex phenomena|On Creativity and Cognition of Cellular Automata]]. Here are 2 [[NetLogo simulations|http://ccl.northwestern.edu/netlogo/models/CA1DRule30]] of rule 22 (using Wolfram's classification of 1D CA), with different initial conditions: 10001 on the left, and 10011 on the right. [<img[rule 22 with 10001|resources/CA22_10001_1.png][resources/CA22_10001.png]] [>img[rule 22 with 10011|resources/CA22_10011_1.png][resources/CA22_10011.png]] Here are a few more results for various different initial conditions progressing as [[Gray codes|https://en.wikipedia.org/wiki/Gray_code]]: [img[rule 22 with all|resources/CA22_all_1.png][resources/CA22_all.png]]
[[The Gnirut Test|http://www.flurb.net/6/6platt.htm]] is (of course :) the reverse (see [[The Most Human Human - by Brian Christian]]) of the [[''Turing Test''|https://plato.stanford.edu/entries/turing-test/]], and as far as I know was originally proposed by [[Charles Platt|https://en.wikipedia.org/wiki/Charles_Platt_(author)]]. The way Platt introduces the concept: >To any thinking computer, the idea that the human brain is capable of achieving machine intelligence seems highly implausible. Human wetware is extremely slow, plagued by unreliable data retrieval, and impaired by tiny input buffers. Its processing power is limited, and its storage is not expandable. > >Some AIs also have questioned whether humans can possess the consciousness and sense of identity that are an everyday reality for even the lowliest computational node with a unique network address. Biological brains suffer from such a high error rate coupled with the constant threat of mortality, we may assume that this “traumatic overhead” interferes with objective self-awareness. > >Still, a few AI devices have claimed persistently that human brains can emulate AIs if they are suitably optimized. To address this contentious issue, the first Gnirut Test was conducted on August 15, 2030. And Platt also provides the rules and procedures for conducting the test, all in good taste/humor. For example, the conclusion of a test conducted: >The test failed to demonstrate that humans are capable of machine intelligence at this time. However, the AI devices that entered the humans in the contest remained adamant that new enhancement techniques may still close the “cognitive gap” and place humans on an equal basis with machines in noncomputational tasks. > >Skeptics were quick to remind observers that the field of human intelligence enhancement has a long history of unduly optimistic predictions, stretching all the way back to the Vingean Singularity, when machines achieved dominance slightly less than ten weeks ago. At this point, most AIs have lost patience with exaggerated claims from the human-intelligence advocates and are ready to move on.
This [[short article by Umberto Eco|http://interglacial.com/pub/text/Umberto_Eco_-_Eternal_Fascism.html]] ([[local copy|resources/Umberto_Eco_Eternal_Fascism.html]]) (author of //The Name of the Rose// (1980), and //Foucault's Pendulum// (1988)) shows some characteristics typical to his style of writing: Complex (or at least not simple) sentences, simple (or at least not bombastic) yet not simplistic ideas, full of (steeped in?) cultural references/connotations, using (sometimes subtle) humor/irony, and __sprinkled with parentheses__ (!). Now, this last feature is (obviously ;-) endearing to me. I was glad to see someone like Eco not shying away from longer/complex sentences and parenthetical remarks, especially since I am aware of (and got some feedback about) these characteristics in //my// style of writing. Here's a sample from [[Eco's article (local copy)|resources/eco_mac_vs_pc.html]]: >Friends, Italians, countrymen, I ask that a Committee for Public Health be set up, whose task would be to censor (by violent means, if necessary) discussion of the following topics in the Italian press. Each censored topic is followed by an alternative in brackets which is just as futile, but rich with the potential for polemic. Whether Joyce is boring (whether reading Thomas Mann gives one erections). Whether Heidegger is responsible for the crisis of the Left (whether Ariosto provoked the revocation of the Edict of Nantes). Whether semiotics has blurred the difference between Walt Disney and Dante (whether De Agostini does the right thing in putting Vimercate and the Sahara in the same atlas). Whether Italy boycotted quantum physics (whether France plots against the subjunctive). Whether new technologies kill books and cinemas (whether zeppelins made bicycles redundant). Whether computers kill inspiration (whether fountain pens are Protestant). >One can continue with: whether Moses was anti-semitic; whether Leon Bloy liked Calasso; whether Rousseau was responsible for the atomic bomb; whether Homer approved of investments in Treasury stocks; whether the Sacred Heart is monarchist or republican. I'll keep reading Eco, specially his articles, to see when he starts using not just parentheses, but also "/" (slashes), [[just like me|Happiness and sorrow]]...
In [[a sound and practical interview|http://www.criticalthinking.org/pages/an-interview-with-linda-elder-about-using-critical-thinking-concepts-and-tools/495]] on her [[website critical thinking|http://www.criticalthinking.org/]], Linda Elder describes her view on "Essential Ideas" in a Knowledge Domain: >In every subject and domain of learning, there are ideas that are seminal and ideas that are peripheral (and many ideas in-between). Essential ideas are seminal. They are at the roots of many derivative ideas. When we know these foundational ideas well, we are able to derive many of the others. They become sources of power in our thinking. For example, one cannot understand physics without understanding the idea of matter and energy. All of physics revolves around these two ideas and their interrelationships. To think like a physicist is to learn how to use these concepts everywhere in one’s thought. > >It is essential ideas that form how we see the world, and how we function in it. Therefore, when studying and learning, and using knowledge resources it is important to notice what the essential idea are, that is, what is the most basic point being made? >if students use this idea in their thinking, they will reason better through the content and function better as learners. > >Take, for example, the essential idea “To understand our experience and the world itself, we must be able to think within alternative world views. We must question our ideas. We must not confuse our words or ideas with things.” >Now image a student taking this idea seriously. This student would continually seek out, and seek to master, multiple viewpoints. The student would routinely question the ideas he is using in his thinking. He would recognize that things are often confused with words. Words often hypnotize us and we use them without reflecting on what they represent. > >Critical thinking reminds us of the power of essential ideas in human thinking: purpose, question, information, concept, inference, implication, point of view, clarity, precision, accuracy, relevance, depth, breadth, logic, and significance. These are essential ideas for our thinking at a critical level. Compare these to the [[Computer Science "Big Ideas", Practices and Skills|The Big Ideas and Computational Practices of Computer Science*]].
I have experienced the strong impact and effects of curiosity on my effectiveness, my learning, and my enjoyment of life over and over. In my mind, curiosity may be more important than courage, when it comes to both objective accomplishments and the subjective sense of accomplishing. I also feel that if one is driven by curiosity, cultivates it, preserves it, and "befriends" it, one has more "wind in their sails", compared with working with courage, which requires "overcoming resistance", since curiosity is part of our nature (just look at babies and small children exploring: "The impulse to seek new information and experiences and explore novel possibilities is a basic human attribute"), whereas courage is something one has to "develop". >As every parent knows, Why? is ubiquitous in the vocabulary of young children, who have an insatiable need to understand the world around them. They aren’t afraid to ask questions, and they don’t worry about whether others believe they should already know the answers. But as children grow older, self-consciousness creeps in, along with the desire to appear confident and demonstrate expertise. By the time we’re adults, we often suppress our curiosity. In an article in the Harvard Business Review titled [["The Business Case for Curiosity"|https://hbr.org/2018/09/curiosity]] Francesca Gino focuses on the workplace and businesses, but I think that many of the aspects she discusses in that context are very relevant and true in education/learning/schools. Also, since Gino claims (and reports on research evidence) that curiosity is important in the business world (and the work environment context), it seems important to cultivate curiosity in the school environment, as a preparation for successful (and enjoyable :) adulthood. !!!A few key points from the article: * cultivating [curiosity] at all levels [of the workplace] helps leaders and their employees adapt to uncertain market conditions and external pressures: When our curiosity is triggered, we think more deeply and rationally about decisions and come up with more-creative solutions. * curiosity leads to seeking and generating alternatives, and thus reduces the risk of decision making errors due to confirmation bias (looking for information that supports our beliefs rather than for evidence suggesting we are wrong) and to stereotyping people (by race, gender, role, age, etc.) * When we are curious, we view tough situations more creatively [as shown in studies]. We also perform better when we’re curious [as demonstrated in performance evaluations on the job]. * Interestingly, "curiosity encourages members of a group to put themselves in one another’s shoes and take an interest in one another’s ideas rather than focus only on their own perspective. That causes them to work together more effectively and smoothly: Conflicts are less heated, and groups achieve better results." * There are barriers to encouraging and maintaining curiosity: ** Leaders often think that letting employees follow their curiosity will lead to a costly mess. *** It is true, "Exploration often involves questioning the status quo and doesn’t always produce useful information. But it also means not settling for the first possible solution—and so it often yields better remedies." * curiosity usually declines the longer we’re in a job. ** Because people [are usually] under pressure to complete their work quickly, they [have] little time to ask questions about broad processes or overall goals. !!!! Ways to encourage curiosity * Model inquisitiveness. Leaders can encourage curiosity throughout their organizations by being inquisitive themselves. Asking questions and listening carefully (as opposed to talking) is very important. ** "Why do we refrain from asking questions? Because we fear we’ll be judged incompetent, indecisive, or unintelligent. Plus, time is precious, and we don’t want to bother people. Experience and expertise exacerbate the problem: As people climb the organizational ladder, they think they have less to learn. Leaders also tend to believe they’re expected to talk and provide answers, not ask questions." * leaders can model curiosity is by acknowledging when they don’t know the answer; that makes it clear that it’s OK to be guided by curiosity. * People with more intellectual humility [(the ability to acknowledge that what we know is sharply limited)] do better in school and at work. Why? When we accept that our own knowledge is finite, we are more apt to see that the world is always changing and that the future will diverge from the present. By embracing this insight, leaders and employees can begin to recognize the power of exploration. * leaders can model inquisitiveness by approaching the unknown with curiosity rather than judgment. As human beings, we all feel an urge to evaluate others—often not positively. We’re quick to judge their ideas, behaviors, and perspectives, even when those relate to things that haven’t been tried before. It is much better to question them instead of judging; this makes them think more deeply about what they are saying/doing/thinking. * Emphasize learning goals and encourage continuous learning. It’s natural to concentrate on results, especially in the face of tough challenges. But focusing on learning is generally more beneficial to us and our organizations. ** "A body of research demonstrates that framing work around learning goals (developing competence, acquiring skills, mastering new situations, and so on) rather than performance goals (hitting targets, proving our competence, impressing others) boosts motivation. And when motivated by learning goals, we acquire more-diverse skills, do better at work, get higher grades in college, do better on problem-solving tasks, and receive higher ratings after training. " * Let employees explore and broaden their interests. Organizations can foster curiosity by giving employees time and resources to explore their interests. * To encourage curiosity, leaders should also teach employees how to ask good questions. They should help employees make the transition from giving good answers to asking good questions.
I came across an [[interview with Neil Gaiman in The Guardian|http://www.theguardian.com/books/2013/oct/24/neil-gaiman-face-facts-need-fiction]], where he was talking about the importance (to individuals and society) of having children read fiction (or in [[Neil Gaiman|http://en.wikipedia.org/wiki/Neil_Gaiman]]'s words: It's essential that children are encouraged to read and have access to fiction if we are to live in a healthy society). I totally agree with [[Neil Gaiman|http://www.neilgaiman.com/About_Neil]], and the fact that he talks about the value of Science Fiction^^1^^ as part of his arguments, made it even more personal (and convincing, since I am a ~Sci-Fi reader :), but as I was reading his arguments, it struck me that some of them are equally true and valid justification for the value and importance of [[Computing Literacy|A Framework for Computational Thinking, Computational Literacy]] and [[programming|Coding is not the new literacy]]. Gaiman says: >Fiction [is] a gateway drug to reading. The drive to know what happens next, to want to turn the page, the need to keep going, even if it's hard, because someone's in trouble and you have to know how it's all going to end … that's a very real drive. And it forces you to learn new words, to think new thoughts, to keep going. To discover that reading per se is pleasurable. So, paraphrasing Gaiman, I think that it is also true that: Computing and programming can be a gateway to creativity. The drive to create and want to make things the way you want them to be, or the way you see them, even if hard, is a very real drive. And it forces you to learn new words, concepts, techniques, and skills. It can definitely be pleasurable. Continuing to paraphrase Gaiman, and putting [his words in square brackets], substituting them with mine ''in bold'': >The simplest way to make sure that we raise literate children is to teach them to ''compute'' [read], and to show them that ''computing'' [reading] is a pleasurable activity. And that means, at its simplest, finding ''programming projects'' [books] that they enjoy, giving them access to ''programming tools'' [those books], and letting them ''program'' [read] them. I don't think there is such a thing as a bad ''programming project'' [book] for children. ''On 'quality' projects'': >Well-meaning adults can easily destroy a child's love of ''computing'' [reading]: stop them ''programming'' [reading] what they enjoy, or give them worthy-but-dull ''projects'' [books] that you like, the 21st-century equivalents of Victorian "improving" literature. You'll wind up with a generation convinced that ''computing'' [reading] is uncool and worse, unpleasant. >We need our children to get on to the ''computing'' [reading] ladder: anything they enjoy ''programming'' [reading] will move them up, rung by rung, into ''computational'' literacy. ''On the transformative power of computing'': >''Computation'' [Fiction] can show you a different world. It can ''create new or modified things in your world'' [take you somewhere you've never been]. Once you've ''seen what's possible with computing'' [visited other worlds, like those who ate fairy fruit], you can never be entirely content with the world that you grew up in. Discontent is a good thing: discontented people can modify and improve their worlds, leave them better, leave them different. ''On the potential for personal betterment'': >If you were trapped in an impossible situation, in an unpleasant place, with people who meant you ill, and someone offered you a temporary escape, why wouldn't you take it? And ''computing'' [escapist fiction] is just that: ''a creative activity'' [fiction] that opens a door, shows the sunlight outside, gives you a place to go where you are in control, are with people you want to be with; and more importantly, during your escape, ''computing'' [books] can also give you knowledge about the world and your predicament, give you weapons, give you armour, real things you can take back into your prison. Skills and knowledge and tools you can use to escape for real. And he concludes optimistically: >We all -- adults and children, writers and readers ''and computers (people who do computing)'' -- have an obligation to daydream. We have an obligation to imagine. It is easy to pretend that nobody can change anything, that we are in a world in which society is huge and the individual is less than nothing: an atom in a wall, a grain of rice in a rice field. But the truth is, individuals change their world over and over, individuals make the future, and they do it by imagining that things can be different. ---- 1 - Neil Gaiman on the connection between creativity, reading, and high tech (and programming :) >I was in China in 2007, at the first party-approved science fiction and fantasy convention in Chinese history. SF had been disapproved of for a long time. At one point I took a top official aside and asked him what had changed? "It's simple," he told me. "The Chinese were brilliant at making things if other people brought them the plans. But they did not innovate and they did not invent. They did not imagine. So they sent a delegation to the US, to Apple, to Microsoft, to Google, and they asked the people there who were inventing the future about themselves. And they found that all of them had read science fiction when they were boys or girls.
In her book //Words Are My Matter -- Writings About Life and Books//, Ursula K. Le Guin has an article (originally a talk given at a meeting of Oregon Literary Arts in 2002) titled [[The Operating Instructions|https://mcpl.monroe.lib.in.us/Mobile/BakerAndTaylor/Excerpt?ISBN=9781618731340&UPC=&position=1]] in which she emphasizes the uniqueness and importance of human imagination: >I think the imagination is the single most useful tool mankind possesses. It beats the opposable thumb. I can imagine living without my thumbs, but not without my imagination. >[...] >"The creative imagination is a tremendous plus in business!^^1^^ We value creativity, we reward it!" In the marketplace, the word creativity has come to mean the generation of ideas applicable to practical strategies to make larger profits. This reduction has gone on so long that the word creative can hardly be degraded further. I don't use it any more, yielding it to capitalists and academics to abuse as they like. But they can't have imagination. > >Imagination is not a means of making money. It has no place in the vocabulary of profit-making. It is not a weapon, though all weapons originate from it, and their use, or non-use, depends on it, as with all tools and their uses. The imagination is an essential tool of the mind, a fundamental way of thinking, an indispensable means of becoming and remaining human. > >We have to learn to use it, and how to use it, like any other tool. Children have imagination to start with, as they have body, intellect, the capacity for language: things essential to their humanity, things they need to learn how to use, how to use well. Such teaching, training, and practice should begin in infancy and go on throughout life. Young human beings need exercises in imagination as they need exercise in all the basic skills of life, bodily and mental: for growth, for health, for competence, for joy. This need continues as long as the mind is alive. > >When children are taught to hear and learn the central literature of their people, or, in literate cultures, to read and understand it, their imagination is getting a very large part of the exercise it needs. > >Nothing else does quite as much for most people, not even the other arts. We are a wordy species. Words are the wings both intellect and imagination fly on. ---- ^^1^^ - John Seely Brown (formerly the director of Xerox PARC, now at Stanford), also talks about the [[critical importance and the uniquely human differentiation of Imagination|Sense-making and learning in the new 21st century environment]]
My father, who had a great sense of humor (very "economical" and wry), told me the following story when I (then in high school) had asked him about the importance of learning/knowing Math (you know: "why do I need to learn this? When will I ever use it?"). It might have been "dangerous timing" to tell one's son this kind of story as a response to this kind of question, but it sure didn't cause me any harm or aversion... :). !!!!Story 1 A high school Math teacher was walking down the street in his hometown, when a sleek and shiny luxury car stops at the curb alongside the teacher, the tinted window rolls down, and a former student of his pops his head out and offers him a ride to wherever he needs to. Although the Math teacher recalled that this former student was ''really bad'' in Math and not necessarily one of his favorite students, he accepts the offer for a ride. On the way, the teacher asks the former student, who obviously is now very very well to do, what he ended up doing in life, and the former student very proudly responds that he is a successful business man, owning his own construction company. Then he very quickly adds that he attributes part of his success to his former Math teacher. When the Math teacher asks him why, the now very rich business man says: see, ever since I learned Math from you, I admired simplicity and sound logic. So, my business model is very simple. I borrow capital from my bank, let's say 1 Million Dollars, with which I build a project. I sell it for a 10% profit, and out of this 10M Dollar profit, I return 1M to the bank, and am left with 9M.... I can only imagine how the Math teacher felt when he left the car, thanking his former student for the lift. !!!!Story 2 In the book "The Drunkard's Walk (How Randomness Rules Our Lives)" by Leonard Mlodinow, I read the following story, also "demonstrating" how important it is to know Math: A few years ago a man won the Spanish national lottery with a ticket that ended in the number 48. Proud of his "accomplishment", he revealed the theory (and skill :) that brought him the riches. "I dreamed of the number 7 for seven straight nights," he said, "and 7 times 7 is 48." So here you have it: it pays to know Math. Closing on a serious note: I read about this on [[Edge|https://www.edge.org/]], in the lecture notes of an insightful [["Short Course in Behavioral Economics"|https://www.edge.org/events/the-edge-master-class-2008-a-short-course-in-behavioral-economics]], attended by some interesting and influential people (like, [[Richard Thaler|https://www.edge.org/memberbio/richard_h_thaler]], [[Danny Hillis|https://www.edge.org/memberbio/w_daniel_hillis]], [[Nathan Myhrvold|https://www.edge.org/memberbio/nathan_myhrvold]], [[Daniel Kahneman|https://www.edge.org/memberbio/daniel_kahneman]], [[Jeff Bezos|https://www.edge.org/memberbio/jeff_bezos]], [[Sendhil Mullainathan|https://www.edge.org/memberbio/sendhil_mullainathan]]). This story was told by [[Sendhil Mullainathan|https://www.edge.org/memberbio/sendhil_mullainathan]] as an example of the importance of applying behavioral economics to understand (and possibly dealing with) poverty. !!!!Story 3 Mullainathan showed a bunch of data on itinerant fruit vendors (all women) in India. Sixty-nine percent of them are constantly in debt to moneylenders who charge 5% per day interest. The fruit ladies make 10% per day profit, so half their income goes to the moneylender. They also typically buy a couple cups of tea per day, as their "routine". Sendhil shows that 1-cup of tea per day less would let them be debt free in thirty days, basically doubling their income from then on. Thirty-one percent of these women have figured that out, so it is not impossible. But the big question is: Why don't the rest of the women do it? Sendhil then showed a bunch of other data arguing that poor people -- even those in the US (who are vastly richer in absolute scale than his Indian fruit vendors) -- do similar things with how they spend food stamps, or manage their payday loans. His argument is that under scarcity there is a systematic effect that you put the discount rate^^1^^ way too high for your own good. With too high a discount rate, you spend for the moment, not for the future. So, you have a cup of tea rather than double your income. ---- ^^1^^ - The discount rate is an essential tool/metric for calculating the discounted cash flow of an investment, which is used to determine how much a series of cash flows in the future is worth as a lump sum total today. So, in our example, if the fruit ladies assume a high discount rate, it will result in them not valuing highly enough the doubling of their income in 30 days (and beyond), compared to the "investment" of giving up 1 cup of tea per day, and that's why they'd prefer the tea now to the much higher income in the future.
In an article about Project Based Learning, titled “Motivating Project-Based Learning: Sustaining the Doing, Supporting the Learning”, Blumenfeld, Soloway, Guzdial, et al. make some good observation about Project-Based Learning in the context of motivation and affective engagement vs. cognitive engagement, and provide some good insights and suggestions for teaching and learning. Mark Guzdial (one of the authors) [[covers this in his blog|https://computinged.wordpress.com/2017/01/06/balancing-cognition-and-motivation-in-computing-education-herbert-simon-and-evidence-based-education/]]. The authors observe: * Student interest and perceived value are enhanced when ** tasks are varied and include novel elements *** but don't sacrifice cognitive engagement, and fall into the trap of turning things into simplistic "edutainment" ** the problem is authentic and has value *** it is important (and difficult) to find topics which are authentic/relevant to students, while having rich, deep, enduring value in a larger context ** the problem is challenging ** there is closure, so that an artifact is created *** artifacts need to require the student to integrate information and use complex thought ** there is choice about what and/or how work is done *** students should be able to select project questions, activities, and artifacts. They should determine how to approach the problem, what steps and resources to employ, and so on ** there is an opportunity to work with others * Students' perception of the role of errors in fostering learning is important. ** Errors are detrimental to learning when they are construed as representing failure to learn. ** When errors are perceived as attempts to make meaning and to solve difficult and demanding problems, errors signal just those cognitive and motivational efforts that are desirable for project-based learning ** Errors are a natural and inevitable consequence of working on potentially ambiguous and ambitious tasks * Teachers should encourage, emphasize, and reward mastery (learning) and not performance (success/delivery). ** teachers should not focus on grades, comparative performance, punishment of risk taking, low level tasks * Teachers can enhance motivation and cognitive engagement by ** creating opportunities for learning by providing access to information ** supporting learning by scaffolding instruction and modeling and guiding students to make tasks more manageable ** encouraging students to use learning and metacognitive processes ** assessing progress, diagnosing problems, providing feedback, and evaluating results * Technology can enhance motivation and learning for both teachers and students through ** enhancing interest and authenticity ** improving access to information ** facilitating active representation (and multi-modality) ** structuring the learning and creation process ** diagnosing and correcting errors ** managing complexity and aiding production **
An anecdote demonstrating why the beautifully succinct and familiar oath to "tell the truth, the whole truth, and nothing but the truth" is important: A teacher assigned a difficult book reading to his students, and on the due date wanted to see whether they’d actually read the impenetrable tome. So he asked one of the students whether they had read the book. Thinking quickly, the student thought they would semantically dodge the bullet and answered: “I haven’t quite finished it yet.” “How far did you get?” asked the teacher. “I haven’t quite started it yet” answered the student. Thus basically demonstrating that sometimes telling part of the truth is essentially telling a lie.
Richard Hamming, in [[a lecture titled "You And Your Research"|https://www.cs.virginia.edu/~robins/YouAndYourResearch.pdf]] given at Bell Labs, talked about the importance of tolerating ambiguity^^1^^ and uncertainty: >There's another trait on the side which I want to talk about; that trait is ambiguity. >It took me a while to discover its importance. Most people like to believe something is or is not true. Great scientists tolerate ambiguity very well. They believe the theory enough to go ahead; they doubt it enough to notice the errors and faults so they can step forward and create the new replacement theory. If you believe too much you'll never notice the flaws; if you doubt too much you won't get started. It requires a lovely balance. But most great scientists are well aware of why their theories are true and they are also well aware of some slight misfits which don't quite fit and they don't forget it. > >Darwin writes in his autobiography that he found it necessary to write down every piece of evidence which appeared to contradict his beliefs because otherwise they would disappear from his mind. When you find apparent flaws you've got to be sensitive and keep track of those things, and keep an eye out for how they can be explained or how the theory can be changed to fit them. >Those are often the great contributions. Great contributions are rarely done by adding another decimal place. It comes down to an emotional commitment. Most great scientists are completely committed to their problem. Those who don't become committed seldom produce outstanding, first-class work. ---- ^^1^^ see [[Carl Sagan on ambiguity|Absence of evidence is not evidence of absence. Neither is it evidence of presence.]]
In a wonderful book titled [[Looking At Mindfulness|http://www.booksuniverseeverything.com/2015/09/22/looking-at-mindfulness-by-christophe-andre/]] the french psychiatrist [[Christophe Andre|http://christopheandre.com/WP/?page_id=164]] combines art, psychology, and practicing mindfulness, to help us live a fuller, more meaningful, more enjoyable life. In the book Andre has a chapter on "Training the mind", where he points out something that is very obvious to anyone who tried sitting meditation for even 5 minutes (a sometimes/somewhat bewildering experience for some beginners): we are swayed back and forth by thoughts and emotions all the time. He writes: >Where do we get this amazing tendency to believe that we are the masters of our minds? And to think our capacities for attention and awareness are obviously established, without the need to work at them? >We seem to imagine that, unlike our muscles, our brain has no need of training and can't be developed. Yet we accept that our body needs training. We know that physical exercise develops our breathing and muscles, that appropriate food is good for our health, and so on. But we are less convinced, or perhaps less well informed, about the similar needs of our mind. Training the mind and mental exercise are also extremely important. At the intellectual level, they help us build up our capacities for thinking and concentration; at the emotional level, they help us block our spontaneous tendencies to become stressed, downcast, angry and all the other lapses to which our everyday lives make us vulnerable. Our psychic abilities generally obey the rules of learning -- the more we practice, the more progress we make. Drawing parallels between exercising, practicing, effort, and improvement in other aspects of life, and out mental abilities clarifies and justifies the need, and hopefully motivates us to practice mindfulness. >[...] So if we want to [make progress], we need to work at it. We accept this when it comes to learning to speak another language, ski or play a musical instrument, but it's harder for us to practice serenity and concentration. >[...] mind training, [and] the practice of mindfulness is particularly necessary for those who have noticed that their mind evades and disobeys them. Not that we should expect to be able to put our mind on a leash and excert total control over it, but we can reestablish a balance of power. Being able to concentrate or to calm down, for example, at times when we need to, doesn't seem to me to be a particularly ambitious or excessive goal. But are we able to do these things? > Practicing mind training routinely every day is good for our health -- it's like fitness training for our awareness.
In a fascinating account of "The Hidden Life of Trees", as [[described by Maria Popova in BrainPickings|https://www.brainpickings.org/2016/09/26/the-hidden-life-of-trees-peter-wohlleben/]], a German forester, Peter Wohlleben, writes about a discovery he had made, about the "sociality" of trees. >Neighboring trees [say, in a forest], scientists found, help each other through their root systems — either directly, by intertwining their roots, or indirectly, by growing fungal networks around the roots that serve as a sort of extended nervous system connecting separate trees. Wohlleben ponders this astonishing sociality of trees, and possible parallels to strong human communities and societies: > >Why are trees such social beings? Why do they share food with their own species and sometimes even go so far as to nourish their competitors? The reasons are the same as for human communities: there are advantages to working together. A tree is not a forest. On its own, a tree cannot establish a consistent local climate. It is at the mercy of wind and weather. But together, many trees create an ecosystem that moderates extremes of heat and cold, stores a great deal of water, and generates a great deal of humidity. And in this protected environment, trees can live to be very old. To get to this point, the community must remain intact no matter what. If every tree were looking out only for itself, then quite a few of them would never reach old age. Regular fatalities would result in many large gaps in the tree canopy, which would make it easier for storms to get inside the forest and uproot more trees. The heat of summer would reach the forest floor and dry it out. Every tree would suffer. > >Every tree, therefore, is valuable to the community and worth keeping around for as long as possible. And that is why even sick individuals are supported and nourished until they recover. Next time, perhaps it will be the other way round, and the supporting tree might be the one in need of assistance. >[…] > >A tree can be only as strong as the forest that surrounds it. Maria Popova ponders: >One can’t help but wonder whether trees are so much better equipped at this mutual care than we are because of the different time-scales on which our respective existences play out. Is some of our inability to see this bigger picture of shared sustenance in human communities a function of our biological short-sightedness? Are organisms who live on different time scales better able to act in accordance with this grander scheme of things in a universe that is deeply interconnected? Which echos [[the sentiment and thought experiments by the German zoologist Karl Ernst von Baer|Our worldview is literally shaped by time]] (in 1860). It is also interesting to compare [[human size/lifespan in perspective|Human life in perspective]]. And Popova continues: >Because trees operate on time scales dramatically more extended than our own, they operate far more slowly than we do — their electrical impulses crawl at the speed of a third of an inch per minute. >[...] >The upside of this incapacity for speed is that there is no need for blanket alarmism — the recompense of trees’ inherent slowness is an extreme precision of signal. In addition to smell, they also use taste — each species produces a different kind of “saliva,” which can be infused with different pheromones targeted at warding off a specific predator. >[...] >In the remainder of The Hidden Life of Trees, Wohlleben goes on to explore such fascinating aspects of arboreal communication as how trees pass wisdom down to the next generation through their seeds, what makes them live so long, and how forests handle immigrants. (It's interesting to compare what Daily Alice (Alice Dale Drinkwater) had to say about trees in the fantastic book "Little, Big": "Did you ever think, that maybe trees are alive like we are, only just more slowly? That what a day is to us, maybe a whole summer is to them - between sleep and sleep, you know. That they have long long thoughts and conversations that are just too slow for us to hear.") """ """ [time scale] [time horizon] [wicked environment] [kind environment]
This is an insightful little book (97 pages, including notes, resources, acknowledgements, and index :) by Jurriaan Kamp, the co-founder of "[[The Intelligent Optimist|http://www.theoptimist.com/]]".
The simple, honest, life-affirming message starts with a keen observation on the first page, in the
!!!Author's Note:
>[...] over many years I have learned that a lot of people choose vocations that they themselves can learn the most from.
(or as [[Joseph Joubert|https://en.wikipedia.org/wiki/Joseph_Joubert]]^^1^^ said: to teach is to learn twice)
>Many psychotherapists have a great need to heal their own psyche.
>Mediators tend to create conflicts in their personal lives.
>High energy motivational speakers [...]
>Business gurus who teach that egos are so often roadblocks [...]
>People who teach meditation and mindfulness tend to need to quiet their own minds.
>It is like healing your own wounds becomes the most important and inspiring contribution you can make to the world around you.
(echos the conviction that "world peace" starts within)
>Then there are also the people who are natural teachers. They don't need to write books [wikis? :)] or tell their stories to big audiences. They just //are//. And through their beings they teach and inspire. Talking or writing about something is different from //being// that same thing. From being flows natural inspiration. No need for books or talks.
(yet here he is (and I'm thankful for his book!), and here I am (and I hope you benefit from this wiki))
!!!In his introduction, Kemp says:
>Media distort reality and breed pessimism. We need optimism for more health, happiness, and success. We need freedom //from// the press to get there.
He had been a journalist for many years, and knows the media world from the inside. He, in effect confirms that "bad news sells copies" (or in his words: "More bombs, more money")
I definitely believe him when he says:
>It all comes from a big misunderstanding. Somehow, somewhere, in the decades since World War II, we have started confusing telling stories -- informing the public -- with selling watches, cars, soda, and toothbrushes.
>Nowadays, publishers are supposed to target certain well-defined interest groups. In fact, each new media initiative starts by defining its audience. As much sense as that seems to make in today's money-driven world, it's unethical. Media's contributions should come from their stories, their content -- not their capacity to serve a certain audience and to attract money from advertisers.
In an interesting aside, Kamp makes the difference between journalism and social media very clear. He brings up a point sometimes argued by people:
>The press doesn't matter any more, some will argue. We have Twitter. News spreads instantly through social media. These days we are all journalists.
And then he compares:
>The evolution of social media certainly brings a lot of good. Whereas the average front page [in the press] is 90 percent frauds, floods, fires, murders, and diseases, research shows that what people share on social media is more positive than negative.The more positive an article, the more likely it's going to be shared, explains Jonah Berger, social psychologist at the University of Pennsylvania, in his book //Why Things Catch On//. And in an interview with the //New York Times// he said, "The 'if it bleeds' [it leads]" rule works for mass media that just want you to tune in. They want your eyeballs and don't care how you're feeling. But when you share a story with your friends and peers, you care a lot more how they react.
So the conclusion is:
>[...] friends care about each other, and tweeting and sharing tend to be more positive.
But, Kamp warns:
>[T]weeting is no journalism. Journalists are trained for years to write good news stories that cover all relevant angles. Good journalism is a trade. It should present and expalin the news. It should investigate and discover. Media should always be on a quest for the truth. Social media should complement that, not replace it.
And a concrete analogy :)
>I've made bookcases for our home. Recently, we hired a carpenter to do the same. I could easily see the difference between his work and mine. I'm definitely not a carpenter.
He finally observes:
>Most news is not helpful to you. It interrupts your thinking. It stands in the way of creativity and the emergence of new ideas. As [[Rolf Dobelli wrote in the Guardian|http://www.theguardian.com/media/2013/apr/12/news-is-bad-rolf-dobelli]], "if you want to come up with old solutions, read news. If you are looking for new solutions, don't".
>So often what is presented as //news// is really //olds//. It is not about innovation, breakthroughs, solutions, or new insights. In short, it's not optimistic. It's about sad repetitions of unfortunate events that don't support and enrich your life. That's very pessimistic.
!!!In chapter 1 - The Best way to Live
Kamp takes a closer look at optimism.
>Optimism doesn't mean denying reality. According to the dictionary, the everyday meaning of //optimism// is "hopefulness and confidence about the future or the success of something".
>But the root of the word comes from Latin (//optimum//) and the more precise definition of optimism is "the doctrine that this world is the best of all possible worlds."
>Optimism is a fundamental attitude. It's not an opinion about reality; it's a starting point for dealing with reality.
and he gives a quote I like:
>If there's no solution, then there's no problem.
In this chapter Kamp also quotes from M. Scott Peck's excellent book //The Road Less Traveled//:
[img[The Road Less Traveled|./resources/Kamp_on_Scott_small.jpg]]
And as a true optimist, he observes:
> There is no bad weather, only inappropriate clothing.
!!!In chapter 3 - How to become an (even better) optimist
Kamp shows the following black and white image and ask the reader to say:
Do you see a horseman coming towards you, or riding away from you?
[img[horseman|./resources/horse_small.jpg]]
>If you saw the horseman coming to you, you tend to have a more optimistic mindset. If you saw the horseman riding away from you, you tend to be more of a pessimist.
!!!In chapter 4 - The world is a better place than you think
Kamp brings up a few common views promoted and propagated in the media, and argues that they are really myths. He claims and brings data to support the claims that:
* We live in the most peaceful era ever (based on data from the book [[The Better Angels of Our Nature|http://stevenpinker.com/publications/better-angels-our-nature]] by Steven Pinker)
* Overpopulation is a myth ("we could comfortably fit all 7 billion people in a country the size of Texas", on average, one family of 4 on a tenth of an acre garden lot :)
* We can feed all these people (the problem is food distribution, not production)
* We are living longer
* Democracy is spreading
* We have more free time (according to the OECD - Organization for Economic Cooperation and Development)
* We are getting richer
* Natural resources abound
* Our food is safer
* Racism is on the decline
!!!In chapter 5 - The best is yet to come
lists some possible (positive!) developments in the future, with the caveat that it is hard to predict (especially the future :)
In the future we may have:
* Growth and energy for all
* Sustainable abundance
* Money that serves people and society
* Meditation for peace (better mindfulness, calming, concentration)
* Mind over matter
* Food which is wholesome
We will be able to
* create our own reality (nano- and bio-technologies)
* change our personalities (neuro-therapy)
and for more of "the good stuff" see [[The Optimist|http://www.theoptimist.com/]]
----
1 - Jurriaan Kamp seems to be very much aligned with Joseph Joubert, judging from a few quotes from the latter:
* on the control we usually have over the choices we make:
** "Misery is almost always the result of thinking."
** "All gardeners live in beautiful places because they make them so."
* on choosing to look at the bright side (ha!) of things: "When my friends are one-eyed, I look at them in profile."
* on living with intention/purpose: "The mind's direction is more important than its progress."
The issue at hand by Gil Fronsdal
<<forEachTiddler
where
'tiddler.tags.contains("book-chapter") && tiddler.tags.contains("The issue at hand")'
sortBy
'tiddler.title'>>
Above the mountains the geese turn into the light again Painting their black silhouettes on an open sky. Sometimes everything has to be inscribed across the heavens so you can find the one line already written inside you. Sometimes it takes a great sky to find that first, bright and indescribable wedge of freedom in your own heart. Sometimes with the bones of the black sticks left when the fire has gone out someone has written something new in the ashes of your life. You are not leaving. Even as the light fades quickly now, you are arriving. ---- Compare to [[The Journey - Mary Oliver]]
One day you finally knew
what you had to do, and began,
though the voices around you
kept shouting
their bad advice–
though the whole house
began to tremble
and you felt the old tug
at your ankles.
“Mend my life!”
each voice cried.
But you didn’t stop.
You knew what you had to do,
though the wind pried
with its stiff fingers
at the very foundations,
though their melancholy
was terrible.
It was already late
enough, and a wild night,
and the road full of fallen
branches and stones.
But little by little,
as you left their voices behind,
the stars began to burn
through the sheets of clouds,
and there was a new voice
which you slowly
recognized as your own,
that kept you company
as you strode deeper and deeper
into the world
determined to do
the only thing you could do–
determined to save
the only life you could save.
----
compare to [[The Journey - David Whyte]]
As a Citizen Teacher teaching a course at [[McNair Middle School|http://www.citizenschools.org/california/about/locations/]] (part of the [[Citizen Schools|http://www.citizenschools.org/california/]]), I am currently teaching a new course I've developed, called "Simplexity - simple rules leading to complex behavior". I'll cover this course after I finish the 10 week/lesson class, but you can see the [[course outline, lesson plans, and student activities/programs|http://employees.org/~hmark/courses/amazingmazes/index.html]]. One of the modules in this course (the modular design enables me to reuse parts/modules elsewhere), is about [[One Dimensional Cellular Automata (1D CA)|Cellular Automaton Rule 110]], which leads to another module on 2D ~CAs (a-la [[Conway's Game Of Life|http://en.wikipedia.org/wiki/Conway%27s_Game_of_Life]]). And this leads to a third module on Fractals and Fractal Curves, one of which is the [[Jurassic Park Dragon|http://en.wikipedia.org/wiki/Dragon_curve]] ([[as shown|resources/jurassic-park-book-dragon.jpg]] in Michael Crichton's book). ''A low-tech way of creating the dragon^^1^^'' start with a narrow strip of paper, say about 1" by 11". Construction paper is good because it has a little more stiffness but plain paper works too. Take the strip and fold the paper over end-to-end, right hand onto left, and crease. Now fold it again in the same way for the second time, right onto left, and crease, and again (3^^rd^^ time), right onto left and crease, and again (4^^th^^) right onto left and crease, and finally, one more time (5^^th^^). So for the first 5 generations, after straightening the folds and creating 90 degree turns (as much as you can with paper) you get: |borderless|k |On the right is the Jurassic Park Dragon^^1^^ after 5 generations.|[img[Fractal Dragon 5 generations|./resources/dragon-fractal-5-gens-small.png][./resources/dragon-fractal-5-gens.png]]|On the right is the step by step construction and "string representation" of 5 generations. R=right turn, L=left turn|[img[Dragon Fractal generations|resources/dragon-fractal-generations-small.png][resources/dragon-fractal-generations-big.png]]| |borderless|k [>img[Dragon Fractal generations|resources/dragon-fractal-generations-rules-small.png][resources/dragon-fractal-generations-rules.png]] Cynthia Lanius, formerly at Rice University, explains the [[steps and rules for evolving this dragon|http://math.rice.edu/~lanius/frac/code.html]], which boils down to this: Rule 1. The middle entry in the table is always a right (R). Rule 2. For the next generation, the entries to the left of the middle are the entries of the table before (i.e. copied, as-is). Rule 3. The entries to the right of the middle are opposites and mirror-images of the ones to the left (i.e. every R is replaced by an L, and the most-left entry determines the most right entry, moving into the middle). [>img[Dragon Fractal generations|resources/dragon-fractal-generations-rules-2-small.png][resources/dragon-fractal-generations-rules-2.png]] Another way to formulate the rules for evolving this dragon is described on [[Joel Castellanos's site|http://cs.unm.edu/~joel/PaperFoldingFractal/chasing.html]] (I switched his Left's and Right's to match the above): Rule 1. The middle entry in the table is always a right (R) (identical to Lanius above). Rule 2. For the next generation, start from left, inserting an R before (to the left of) the first letter, and then insert a letter after every letter of the previous generation, //alternating// between inserting an L and an R. !!!!So, is there a way to create the Dragon by a set of Elementary 1 Dimensional Cellular Automata rule? [>img[Dragon Fractal generations|resources/dragon-fractal-generations-no-rules-small.png][resources/dragon-fractal-generations-no-rules.png]] There are a few problems trying to do that. 1. If you look at the rows/generations in the image below, you can see that there are actually 3 values that each cell can take (L, R, blank), as opposed to two in 1D CA (on, off). 2. The value of a cell in the next generation is not //consistently// determined by it's 3 cell neighbors in the current generation. For example, the central cell in generation 3 (R) is determined by it's 3 cell neighbors in gen. 2 which are RRL. But, the RRL neighbors in gen. 3 result in L in gen. 4 in one instance, and in an R in another instance. !!!!But, is there a way to generate the Dragon sequence using a Turing Machine? [>img[Dragon Fractal as a Turing Machine|resources/Dragon_Turing_small.jpg][resources/Dragon_Turing.jpg]]It turns out that you can generate the Dragon Curve sequence without generating/knowing the previous generation of the Dragon, using a Turing Machine consisting of 4 rules. As you may know, a Turing Machine has an infinite paper tape, where a reading/writing "head" can read from and write to, based on following certain rules. Our simple Turing Machine in this case will have a reading head starting to read at position 1 of a paper tape, with only the number 1 written on it. For simplicity, the Turing Machine will have a writing head, initially positioned at position 2 of the tape, ready to write something down, based on the following rules: * If the reading head reads 0 - the writing head will write 0 followed by 1 * if the reading head reads 1 - the writing head will write 3 and 2 * if the symbol read is 2, write 42 * if the symbol read is 3, then write 31 * and if the symbol read is 4, write 41 Note that the reading head reads one symbol from the tape at the position it is on, then the writing head writes the symbols on the tape at the position it is on, per the applicable rule. So, if the tape has the symbol 1 at the first position of the tape, and the reading head is on position 1, and the writing head is at position 2, we get after one iteration, at tape which looks like this: * 132 (the first/left 1 is the initial symbol on the tape. The reading head reads it, and following the second rule above, the writing head positioned at position 2 (initially empty - with no symbols on the tape) writes 3 followed by 2, resulting in 1 3 2. After this, the reading head moves to the next position on the tape (looking at the 3 which had been just written by the writing head), while the writing head moves to position 4 (an empty space on the tape, right of the last symbol (2) it had just written) The next iteration will result in a tape looking like: * 13231 after which the reading tape will now be on the symbol 2, and the writing head will be on an empty space on the right of the right 1 The next reading/writing iteration (reading the 2 and writing 42 as a result) generates: * 1323142 The Turing Machine can go on forever following the rules and generating the tape shown in the image above. In order to get the Dragon sequence, you need to take the tape and interpret it the following way: * Replace each even number on it with a 0, and each odd number with a 1 ** So what you get for the sequence 1323142 is: 1101100 * Interpret each 0 as a Left turn (L), and every 1 as a Right turn (R) ** So what you get is: RRLRRLL Which is the sequence of the first few foldings (Generation 3) for the Dragon as we have seen above. ------------------------------ ^^1^^ snapshot of the [[fractal applet|http://employees.org/~hmark/courses/simplexity/FractalGrower.jnlp]] originally from [[Joel Castellanos's Fractal Grower site|http://cs.unm.edu/~joel/PaperFoldingFractal/paper.html]], which is a ''high-tech (Java Applet) way of creating the Dragon'' [img[Dragon Fractal 10 generations|resources/dragon-10-gen.png][resources/dragon-10-gen.png]][>img[Dragon Fractal 14 generations|resources/dragon-14-gen.png][resources/dragon-14-gen-big.png]] The Dragon after 10 generations (left) and 14 generations (right).
Mid-way through [[teaching a course|The "Acing Racing" course]] at Citizen Schools, I suggested to the school principal to look into using the [[Khan Academy|http://www.khanacademy.org/about]] as a math remediation/augmentation tool for the kids that either struggle with basic math concepts and techniques, or kids who can and want to push forward. I especially like the knowledge map of all the math topics and their dependencies, the fact that kids can progress at their own pace, and that they have to show mastery (do 10 exercises in a row correctly at each level) before moving to another topic. I found it interesting that a few key capabilities implemented in the Khan Academy tutoring system were principles and features I introduced into an on-line tutoring system I had designed as part of [[my studies at Stanford (in the Learning, Design, and Technology MA program)|http://ldtprojects.stanford.edu/~hmark/]]. In that system, I represented the knowledge domain as a [[topic map|./resources/LDTtutoringSystemTopicMap1.png]], with topics and relationships indicating dependencies and levels of difficulty. Associated with each topic in the topic map, were [[banks of questions/exercises|./resources/LDTtutoringSystemQuestionBanks1.png]] that the learner had to master, before moving to the next level/topic. Since proficiency is very important, [[the Khan Academy system tracks and monitors the kids' activities, progress and mastery|./resources/KhanAcademyPerformanceMonitor1.png]], and allows the kids and their mentor/coach/teacher/parent to see exactly what they did, when, how, etc. This way of monitoring reminds me very much of a similar capability I designed into the on-line tutoring system, where the system tracked and reported via [[a virtual 3D monitor|./resources/LDTtutoringSystemMonitor1.png]] what topics the learner covered (1st dimension - domain knowledge), when and how long it took (the 2nd dimension - time), and how they performed (the 3rd dimension - mastery level). One key feature (and selling point?) of the Khan Academy platform is the large tutorial videos library. I always had mixed feelings about their effectiveness and contribution to student learning, and I got some validation from [[a report on a pilot of blended learning|resources/lessons-learned-from-a-blended-learning-pilot4.pdf]]: >''Value of the Videos'' >A final interesting perspective on Khan involves the value of the site’s videos. Most people are drawn to Khan based on its massive video library and Sal’s own charming and engaging teaching style. Like many, we assumed the videos would be the predominant learning mechanism for students tackling new material. In fact, the students rarely watched the videos. This result is consistent with some of the observations in the Los Altos pilot. The students greatly preferred working through the problem sets to watching the videos. Students turned to their peers, the hint, and the classroom teacher much more often than they did the linked Khan video. >One possible reason is that the videos are aligned to the broader concept, but do not link directly to the problem students are struggling with. A second hypothesis is that the videos may be too long at eight to ten minutes. If students have 60-‐90 minutes to work through multiple concepts in a class period, an investment of ten minutes for a single video feels like a lot. The badges and stars within Khan may also be a disincentive, as there is no immediate reward for watching videos as there is when completing streaks. Lastly, we wonder how many of us really enjoy watching instructional videos for extended periods of time. We are left curious about whether Khan’s videos need to be even more modular and shorter in duration and also about the value of video based instruction.
We all know (and some of us heard in person :) Neil Armstrong's ([[1930-2012|http://www.theatlantic.com/photo/2012/08/neil-armstrong-1930-2012/100359/]]) famous words upon landing and stepping on the Moon (or at least [[we think we know|http://www.ndtv.com/world-news/is-neil-armstrongs-famous-moon-landing-quote-really-a-misquote-524458]]^^1^^), (see [[Moon myth and reality]]), [[but|http://www.space.com/18910-apollo-17-anniversary-men-left-moon.html]], On December 14, 1972 at 5:54:37 p.m. EST, humans left the moon for what would turn out to be the last time. The commander of the Apollo 17 mission, Gene Cernan, had said: > As I take man's last step from the surface, back home for some time to come (but we believe not too long into the future), I'd like to just say what I believe history will record: That America's challenge of today has forged man's destiny of tomorrow. And, as we leave the Moon at ~Taurus-Littrow, we leave as we came and, God willing, as we shall return: with peace and hope for all mankind. But, according to Apollo 7 astronaut Walter Cunningham in his book The ~All-American Boys, Cernan's final words on the moon were: "Let's get this mother out of here." (Or as [[Miles O'Brien spells it|http://boingboing.net/2012/12/14/we-left-the-moon-40-years-ago.html]], awesomely, "let's get this mutha.") But, but, the "outta here" thing is likely, alas, apocryphal [i.e., of doubtful authorship or authenticity]. According to NASA's official transcript of Apollo 17's return to Earth, what Cernan actually said last, was in part a response to a malfunction his fellow astronaut, Jack Schmitt, was encountering with a camera: "Now, let's get off. Forget the camera." From [[The Atlantic Magazine|http://www.theatlantic.com/technology/archive/2012/12/what-were-the-last-words-spoken-on-the-moon/266287/]] ---- ^^1^^ - see [[GD local copy|https://docs.google.com/document/d/1PAsseF0KS2ka3L6CbT3b6krwXcY3688JAJRy5RkAPHA/edit?usp=sharing]]
>[...] it is a strange thing that most of the feeling we call religious, most of the mystical outcrying which is one of the most prized and used and desired reactions of our species, is really the understanding and the attempt to say that man is related to the whole thing, related inextricably to all reality, known and unknowable. This is a simple thing to say, but the profound feeling of it made a Jesus, a St. Augustine, a St. Francis, a Roger Bacon, a Charles Darwin, and an Einstein. Each of them in his own tempo and with his own voice discovered and reaffirmed with astonishment the knowledge that all things are one thing and that one thing is all things plankton, a shimmering phosphorescence on the sea and the spinning planets and an expanding universe, all bound together by the elastic string of time. It is advisable to look from the tide pool to the stars and then back to the tide pool again. (another [[beautiful quote|The Log from the Sea of Cortez - one-ness]] from The Log from the Sea of Cortez)
>It seems apparent that species are only commas in a sentence, that each species is at once the point and the base of a pyramid, that all life is relational to the point where an Einsteinian relativity seems to emerge. And then not only the meaning but the feeling about species grows misty. One merges into another, groups melt into ecological groups until the time when what we know as life meets and enters what we think of as non-life: barnacle and rock, rock and earth, earth and tree, tree and rain and air. And the units nestle into the whole and are inseparable from it... It is advisable to look from the tide pool to the stars and then back to the tide pool again. I suspect it's //not// a coincidence that the fluidity that Steinbeck describes here is reflected in human associativity or free association, [[captured so simply and vividly by Aristotle|Free association]]. It really makes one wonder what is causing what: is the inter-relatedness of the universe causing us to perceive associatively, or is our associative perception creating (//creating?!//) an inter-related universe. ([[another strange loopiness|http://en.wikipedia.org/wiki/I_Am_a_Strange_Loop]] a-la Douglas Hofstadter?) (another [[beautiful quote|The Log from the Sea of Cortez - awe]] from The Log from the Sea of Cortez)
One of the interesting and successful [[collaborations in math, between G.H. Hardy and S. Ramanujan|http://www.storyofmathematics.com/20th_hardy.html]] (from 1914 to 1919) is captured in a moving movie titled //The man who knew infinity// (based on a book by Robert Kanigel, starring Jeremy Irons and Dev Patel). Hardy was a (devout :) atheist, whereas Ramanujan was a believer, who claimed that he got his mathematical ideas and inspirations from a "divine source". Hardy found it very hard to deal with this, and constantly insisted that Ramanujan develop rigorous proofs to his "miraculous insights". (It turns out Hardy was right to insist on proofs - Ramanujan's divine insight about a certain theory on prime numbers was erroneous; he had been brilliantly right about other theories/insights though). At one point in the movie, Ramanujan tells Hardy that the significance and meaning of his math theories and ideas is only valuable because he believes they come from God (gods). This brings up the question of whether math is discovered by humans or invented by them. This is obviously an open philosophical question, but it reminds me of the [[insightful response of Mario Livio|Is Math a human invention or a series of discoveries of truths in the real world?]] who basically said that he believes that: - humans __abstract__ the basic math concepts (such as number, line, set, etc.) from reality - so there is an __"invention""__ element in this (and this attests to human //both// greatness and limits, since we have to abstract to both gain new knowledge, but also in order not to drown in the overwhelming torrent of details that reality hits us with) - then, we __"discover"__ relationships between, and (human-scale) significance in, these concepts. So math has //both// elements of invention //and// discovery. This echos [[David Darling's view|The relationship between the world out there and what's inside our mind]] that we combine perception and classification of "things out there" with mental processes in the mind as our natural/inherent mode of living and surviving. How Ramanujan was able to invent and discover his ideas and whether the "invocation of god" is necessary/sufficient is a good question. I don't think that if we don't understand the process (by which Ramanujan was able to come up with his ideas) we need to assume "divine intervention". As Carl Sagan had said: [[Absence of evidence is not evidence of absence. Neither is it evidence of presence.]] So, in my mind, the last part of the above quote (which is often forgotten), says that not knowing the answer is not "the end of the road", but rather is an exciting invitation to try and figure out/research the causes and not "close the door" by invoking divinity as the ultimate/satisfactory answer.
From the beautifully decorated book, full of math-inspired/generated graphics and pictures, here is a collection of excerpts and quotes "celebrating the wisdom and beauty of mathematics" (with some comments and "action items" for me :): * The trouble with integers is that we have examined only the small ones. Maybe all the exciting stuff happens at really big numbers, ones we can't get our hands on, or even begin to think about in any very definitive way. So maybe all the action is really inaccessible and we're just fiddling around. Our brains have evolved to get us out of the rain, find where the berries are, and keep us from getting killed. Our brains did not evolve to help us grasp really large numbers or look at things in a hundred thousand dimensions. ** Ronald Graham, quoted in Paul Hoffman's [[The Man Who Loved Only Numbers|https://cs.brynmawr.edu/Courses/cs231/fall2013/lecs/erdos.pdf]], in The Atlantic, 1987 (and [[Hoffman's "marvelous, vivid, and strangely moving" full book|https://bobson.ludost.net/copycrime/35559997-Man-Who-Loved-Only-Numbers-Paul-Hoffman.pdf]]) *** this may be true to a certain extent, but should be revised in light of the work which has been done on "monstrous" prime numbers - [[TED talk by Adam Spencer|https://www.youtube.com/watch?v=B4xOFsygwr4]] *** one should also temper the above statement in light of [[the work of Georg Cantor|https://www.scientificamerican.com/article/strange-but-true-infinity-comes-in-different-sizes/]] on the variety of infinities (where some are simply larger than others). * Archimedes will be remembered when Aeschylus is forgotten, because languages die and mathematics ideas do not. 'Immortality' may be a silly word, but probably a mathematician has the best chance of whatever it may mean. ** G. H. Hardy, [[A Mathematician's Apology|https://www.math.ualberta.ca/mss/misc/A%20Mathematician%27s%20Apology.pdf]], 1941 *** Aeschylus was a Greek, often described as the father of tragedy. * The Gedemondan chuckles. 'We read probabilities. You see, we see - perceive is a better word - the math of the Well of Souls. We feel the energy flow, the ties and bands, in each and every particle of matter and energy. All reality is mathematics, all existence - past, present, and future - is equations.' ** Jack Chalker, [[Quest for the Well of Souls|https://en.wikipedia.org/wiki/Quest_for_the_Well_of_Souls]], 1978 *** check out the book * One sign of an interesting program is that you cannot readily predict its output. ** Brian Hayes, //On the Bathtub Algorithm for ~Dot-Matrix Holograms//, Computer Language, 1986 *** check: is this //the// Brian Hayes of Hayes Modems fame/lore? *** were there any randomly generated programs/artforms generated in 1986? **** how about the Mandelbrot Fractal and the Julia Set? * While the equations represent the discernment of eternal and universal truths, however, the manner in which they are written is stricktly, provincially human. That is what makes them so much like poems, wonderfully artful attempts to make infinite realities comprehensible to finite beings. ** Michael Guillen, //Five Equations that changed the World//, 1996 *** great quote about the beauty and poetry in math *** check out the book * The generation of random numbers is too important to be left to chance. ** The title of Robert Coveyou's paper, which appeared in //Studies in Applied Mathematics//, 1969 *** read the paper * Applications, computers, and mathematics form a tightly coupled system yielding results never before possible and ideas never before imagined. ** Lynn Arthur Steen, //The Science of Patterns//, Science, 1988 *** read the article *** examples of the "tight couplings" he had in mind? * Science is not about control. It is about cultivating a perpetual condition of wonder in the face of something that forever grows one step richer and subtler than our latest theory about it. It is about reverence, not mastery. ** Richard Powers, //The Gold Bug Variations//, 1991 *** check it out *** great quote about the nature of science and the beauty of it * It's like asking why Beethoven's Ninth Symphony is beautiful. If you don't see why, someone can't tell you. I know numbers are beautiful. If they aren't beautiful, nothing is. ** Paul Erdos, quoted in Paul Hoffman's [[The Man Who Loved Only Numbers|https://cs.brynmawr.edu/Courses/cs231/fall2013/lecs/erdos.pdf]], in The Atlantic, 1987 (and [[Hoffman's "marvelous, vivid, and strangely moving" full book|https://bobson.ludost.net/copycrime/35559997-Man-Who-Loved-Only-Numbers-Paul-Hoffman.pdf]]) *** compare with the quote by Kurt Vonegut quoting his uncle: //If this isn't nice, what is?// *** I have the book; check out the Atlantic article * In principle ... [the Mandelbrot Set] could have been discovered as soon as men learned to count. But even if they never grew tired, and never made a mistake, all the human beings who have ever existed would not have sufficed to do the elementary arithmetic required to produce a Mandelbrot Set of quite modest magnification. ** Arthur C. Clarke, //The Ghost from the Grand Banks//, 1990 *** on the power and insights made possible by computers *** check out the book * Mathematicians study structure independent of context, and their science is a voyage of exploration through all the kinds of structure and order which the human mind is capable of discerning. ** Charles Pinter, //A Book of Abstract Algebra//, 1982 *** check out the book * The bottom line for mathematicians is that the architecture has to be right. In all the mathematics that I did, the essential point was to find the right architecture. It's like building a bridge. Once the main lines of the structure are right, then the details miraculously fit. The problem is the overall design. ** Freeman Dyson, interview with Donald J. Albers, //The College Mathematics Journal//, 1994 ** speaking like a true computer designer/architect ** I can also relate to the truth and beauty of this from personal experience: the sense that once you have the a good (the right? is there only one?) framework, everything seems to snap together nicely. * Now one may ask, "What is mathematics doing in a physics lecture?" We have several possible excuses: first, of course, mathematics is an important tool, but that would only excuse us for giving the formula in two minutes. On the other hand, in theoretical physics we discover that all our laws can be written in mathematical form; and that this has a certain simplicity and beauty about it. So, ultimately, in order to understand nature it may be necessary to have a deeper understanding of mathematical relationships. But the real reason is that the subject is enjoyable, and although we humans cut nature up in different ways, and we have different courses in different departments, such compartmentalization is really artificial, and we should take our intellectual pleasures where we find them. ** Richard Feynman, //[[The Feynman Lectures on Physics|http://www.feynmanlectures.caltech.edu/]]// 1963 ** here Feynman echos a deep assumption that math is at the foundation of nature. Is this math only formula- and equation-based? It'd be interesting to compare/contrast this math to (Wolfram's "New Science" concept with it's Cellular Automata (CA) based rules and behaviors. But then, this could be "subsumed" under "New Math" of course :) * There are tetradic, pandigit, and prime-factorial + 1 primes. And there are Cullen, multifactorial, beastly palindrome, as well as anti-palindrome primes. Then add to these the strobogrammatic, subscript, internal repdigit, and elliptic primes. In fact a whole new branch of mathematics is evolving that deals specifically with the attributes of the various kinds of prime numbers. Yet understanding primes is only part of our quest to fully understand the number sequence and all of its delightful peculiarities. ** Calvin Clawson, //Mathematical Mysteries//, 1996 ** [[Clawson is quoted and primes are discussed in the Journal of International Transdisciplinary Psychology|http://transdisciplinarypsych.org/2012/04/20/prime-numbers-enigma-variations-and-arthur-koestlers-window-on-infinity/]] ** check out the book ** check the types of primes and numbers mentioned * We can imagine that this complicated array of moving things which constitutes “the world” is something like a great chess game being played by the gods, and we are observers of the game. We do not know what the rules of the game are; all we are allowed to do is to watch the playing. Of course, if we watch long enough, we may eventually catch on to a few of the rules. The rules of the game are what we mean by fundamental physics. Even if we knew every rule, however, we might not be able to understand why a particular move is made in the game, merely because it is too complicated and our minds are limited. If you play chess you must know that it is easy to learn all the rules, and yet it is often very hard to select the best move or to understand why a player moves as he does. So it is in nature, only much more so; but we may be able at least to find all the rules. Actually, we do not have all the rules now. (Every once in a while something like castling is going on that we still do not understand.) Aside from not knowing all of the rules, what we really can explain in terms of those rules is very limited, because almost all situations are so enormously complicated that we cannot follow the plays of the game using the rules, much less tell what is going to happen next. We must, therefore, limit ourselves to the more basic question of the rules of the game. If we know the rules, we consider that we “understand” the world. ** Richard Feynman, //[[The Feynman Lectures on Physics|http://www.feynmanlectures.caltech.edu/I_02.html]]// 1963 ** Feynman makes the analogy between physics and math, and chess and rules. Are the rules necessarily expressed in math formulas/equations? * No one really understood music unless he was a scientist, her father had declared, and not just a scientist, either, oh, no, only the real ones, the theoreticians, whose language was mathematics. She had not understood mathematics until he had explained to her that it was the symbolic language of relationships. 'And relationships,' he had told her, 'contained the essential meaning of life.' ** Pearl S. Buck, //The Goddess Abides//, 1973 ** check out the book * Almost your entire mathematical life has been spent on the real line and in real space working with real numbers. Some have dipped into complex numbers, which are just the real numbers after you throw in i. Are these the only numbers that can be built from the rationals? The answer is no. There are entire parallel universes of number that are totally unrelated to the real and complex numbers. Welcome to the world of p-adic analysis - where arithmetic replaces the tape measure and numbers take on a whole new look. Here we will explore this new notion of number and discover its impact on arithmetic, geometry, and calculus. It turns out that p-adic analysis not only dramatically simplifies many mathematical areas but also provides a powerful tool for analyzing number theoretic issues. ** Professor Edward Burger, //[[Exploring p-adic Numbers|https://www.math.ksu.edu/courses/syllabi/math-old/burger.htm]]//, 2013 ** check out his book: Exploring the Number Jungle: A Journey into Diophantine Analysis by Edward B. Burger, American Mathematical Society, 2000 * At this point an enigma presents itself which in all ages has agitated inquiring minds. How can it be that mathematics, being after all a product of human thought which is independent of experience, is so admirably appropriate to the objects of reality? Is human reason, then, without experience, merely by taking thought, able to fathom the properties of real things? In my opinion the answer to this question is, briefly, this: As far as the laws of mathematics refer to reality, they are not certain; and as far as they are certain, they do not refer to reality. ** Albert Einstein in his lecture //[[Geometry and Experience|http://todayinsci.com/E/Einstein_Albert/Einstein-GeometryAndExperience.htm]]// at the Prussian Academy of Science in Berlin, 1921 * [[Gödel proved|resources/Boolos-godel-in-single-syllables.pdf]] that the world of pure mathematics is inexhaustible; no finite set of axioms and rules of inference can ever encompass the whole of mathematics; given any set of axioms, we can find meaningful mathematical questions which the axioms leave unanswered. I hope that an analogous situation exists in the physical world. If my view of the future is correct, it means that the world of physics and astronomy is also inexhaustible; no matter how far we go into the future, there will always be new things happening, new information coming in, new worlds to explore, a constantly expanding domain of life, consciousness, and memory. ** Freeman Dyson, //[[Time without End: Physics and Biology in an Open Universe|http://www.aleph.se/Trans/Global/Omega/dyson.txt]]//, 1979 ** also quoted in //[[Gödel and Physics|http://arxiv.org/pdf/physics/0612253.pdf]]// * Nothing comforted Sabine like long division. That was how she had passed time waiting for Phan and then Parsifal to come back from their tests. She figured the square root of the date while other people knit and read. Sabine blamed much of the world's unhappiness on the advent of calculators. ** Ann Patchett, //The Magician's Assistant//, 1998 ([[chapter 1 in the New York Times|https://www.nytimes.com/books/first/p/patchett-magician.html]]) ** check out the book * I abandoned the assigned problems in standard calculus textbooks and followed my curiosity. Wherever I happened to be - a Vegas casino, Disneyland, surfing in Hawaii, or sweating on the elliptical in Boesel's Green Microgym - I asked myself, "Where is the calculus in this experience?” ** Jennifer Ouellette, //The Calculus Diaries: How Math Can Help You Lose Weight, Win in Vegas, and Survive a Zombie Apocalypse//, 2010 ** check out the book ** as a [[science writer, Jennifer Ouellette|http://twistedphysics.typepad.com/]] has [[insightful observations|Beginner's Mind when teaching]] about communicating science (and teaching) * Like works of literature, mathematical ideas help expand our circle of empathy, liberating us from the tyranny of a single, parochial point of view. Numbers, properly considered, make us better people. ** Daniel Tammet, //Thinking In Numbers: On Life, Love, Meaning, and Math//, 2013 ** From [[Brainpickings|https://www.brainpickings.org/2013/08/05/daniel-tammet-thinking-in-numbers/]]: Daniel Tammet was born with an unusual mind - he was diagnosed with high-functioning autistic savant syndrome, which meant his brain’s uniquely wired circuits made possible such extraordinary feats of computation and memory as learning Icelandic in a single week and reciting the number pi up to the 22,514th digit. He is also among the tiny fraction of people diagnosed with synesthesia — that curious crossing of the senses that causes one to “hear” colors, “smell” sounds, or perceive words and numbers in different hues, shapes, and textures. * It would be very discouraging if somewhere down the line you could ask a computer if the Riemann hypothesis is correct and it said, "yes, it is true, but you won't be able to understand the proof." ** Ronald Graham, //The Death of Proof//, Scientific American, 1993 ** [[Ron Graham|http://www-history.mcs.st-and.ac.uk/Biographies/Graham.html]] is a well-known mathematician (one claim to fame of his is his [[Erdos number|https://en.wikipedia.org/wiki/Erd%C5%91s_number]]: 2). But I find it hard to conceive that computer programs will be able to generate proofs which are not human-conceivable. Math is a human invention (I believe, it's ''not'' a discovery), and computers are too. It will take some sort of "meta-cognition" on the computer part to ''truly'' infer (as opposed to just "say"/print that humans will not understand something. A computer/program will really need to "understand" in order to say that. ** check out the article * //A History of Pi//, Peter Deckmann, 1976 |borderless|k |[img[Pi Spiral|resources/pi1pic.jpg][resources/pi1.jpg]]|[>img[Pi in Scratch|resources/Scratch_pi.png][https://scratch.mit.edu/projects/84155498/#fullscreen]]| |borderless|k [img[Pi Spiral|resources/pi1text.jpg][resources/pi1.jpg]] a picture of pi with an "endless" spiral of pi digits //surrounding/circumventing// it - nice [[idea for an artistic programming project|resources/pi day scratch project.png]]? * When you discover mathematical structures that you believe correspond to the world around you ... you are communicating with the universe, seeing beautiful and deep structures and patterns that no one without your training can see. The mathematics is there, it's leading you, and you are discovering it. Mathematics is a profound language, an awesomely beautiful language. For some, like Leibniiz, it is the language of God. I'm not religious, but I do believe that the universe is organized mathematically. ** Anthony Tromba, //UCSC Professor Seeks to Reconnect Mathematics to its Intellectual Roots//, University of California Press Release 2003 ** check out the press release ** Again, is math a human invention or a human discovery? * As the island of knowledge grows, the surface that makes contact with mystery expands. When major theories are overturned, what we thought was certain knowledge gives way, and knowledge touches upon mystery differently. This newly uncovered mystery may be humbling and unsettling, but it is the cost of truth. Creative scientists, philosophers, and poets thrive at this shoreline. ** W. Mark Richardson, //A Skeptic's Sense of Wonder//, Science, 1998 ** check out the article ** A beautiful metaphor of knowledge island and mystery surface. Mathematically speaking, in the case of fractals, there are fractal curves like the [[Koch Curve/Snowflake|https://en.wikipedia.org/wiki/Koch_snowflake]], which do even "better" than that: they maintain a fixed surface as their length/circumference grows to infinity! * As a teacher, Tengo pounded into his students' heads how voraciously mathematics demanded logic. Here things that could not be proven had no meaning. but once you had succeeded in proving something, the world's riddles settled into the palm of your hand like a tender oyster. ** Haruki Murakami, [[1Q84|https://en.wikipedia.org/wiki/1Q84]], 2011 ** check out the book * H. G. Wells on Math - still relevant today (100+ years later) * Since Galileo's time, science has become steadily more mathematical. ... It is virtually an article of faith for most theoreticians ... that there exists a fundamental equation to describe the phenomenon they are studying ... Yet ... it may eventually turn out that fundamental laws of nature do not need to be stated mathematically and that they are better expressed in other ways, like the rules governing the game of chess. ** Graham Farmelo, Foreword to [[It Must Be Beautiful|http://math.arizona.edu/~faris/equations7.pdf]], 2003 ** Can these "other ways" referring to what Stephen Wolfram calls (rule- and Finite Automata-based) "New Science"? ** check out the book [img[Dice|resources/dice_triangle_small.jpg][resources/dice_triangle.jpg]] ** a picture of a Penrose-inspired [["Impossible Triangle"|https://en.wikipedia.org/wiki/Penrose_triangle]] of dice - nice idea for a statistics-calculator programming project? ** a cool take on Penrose's impossible triangles: impossible cubes (from [[Gábor Damásdi's Symmetry tumblr site|http://szimmetria-airtemmizs.tumblr.com/post/145755776123/impossible-cubes]], inspired by [[Oscar Reutersvärd|https://en.wikipedia.org/wiki/Oscar_Reutersv%C3%A4rd]]’s [[optical illusions and impossible art|http://im-possible.info/english/]]) [img[cubes|resources/impossible cubes.gif][resources/impossible cubes.gif]] * not covered yet: ** pages: 155, 159, 166, 167, 170, 173, 178, 184,
This is a courageous account of the experience Gould had with cancer. He was able to remain calm, level-headed, optimistic, and cool/scientific about it, which may have created a (helpful) positive feedback/result on top of the good luck he surely had. My life has recently intersected, in a most personal way, two of Mark Twain's famous quips. One I shall defer to the end of this essay. The other (sometimes attributed to Disraeli), identifies three species of mendacity, each worse than the one before - lies, damned lies, and statistics. Consider the standard example of stretching the truth with numbers - a case quite relevant to my story. Statistics recognizes different measures of an "average," or central tendency. The mean is our usual concept of an overall average - add up the items and divide them by the number of sharers (100 candy bars collected for five kids next Halloween will yield 20 for each in a just world). The median, a different measure of central tendency, is the half-way point. If I line up five kids by height, the median child is shorter than two and taller than the other two (who might have trouble getting their mean share of the candy). A politician in power might say with pride, "The mean income of our citizens is $15,000 per year." The leader of the opposition might retort, "But half our citizens make less than $10,000 per year." Both are right, but neither cites a statistic with impassive objectivity. The first invokes a mean, the second a median. (Means are higher than medians in such cases because one millionaire may outweigh hundreds of poor people in setting a mean; but he can balance only one mendicant in calculating a median). The larger issue that creates a common distrust or contempt for statistics is more troubling. Many people make an unfortunate and invalid separation between heart and mind, or feeling and intellect. In some contemporary traditions, abetted by attitudes stereotypically centered on Southern California, feelings are exalted as more "real" and the only proper basis for action - if it feels good, do it - while intellect gets short shrift as a hang-up of outmoded elitism. Statistics, in this absurd dichotomy, often become the symbol of the enemy. As Hilaire Belloc wrote, "Statistics are the triumph of the quantitative method, and the quantitative method is the victory of sterility and death." This is a personal story of statistics, properly interpreted, as profoundly nurturant and life-giving. It declares holy war on the downgrading of intellect by telling a small story about the utility of dry, academic knowledge about science. Heart and head are focal points of one body, one personality. In July 1982, I learned that I was suffering from abdominal mesothelioma, a rare and serious cancer usually associated with exposure to asbestos. When I revived after surgery, I asked my first question of my doctor and chemotherapist: "What is the best technical literature about mesothelioma?" She replied, with a touch of diplomacy (the only departure she has ever made from direct frankness), that the medical literature contained nothing really worth reading. Of course, trying to keep an intellectual away from literature works about as well as recommending chastity to Homo sapiens, the sexiest primate of all. As soon as I could walk, I made a beeline for Harvard's Countway medical library and punched mesothelioma into the computer's bibliographic search program. An hour later, surrounded by the latest literature on abdominal mesothelioma, I realized with a gulp why my doctor had offered that humane advice. The literature couldn't have been more brutally clear: mesothelioma is incurable, with a median mortality of only eight months after discovery. I sat stunned for about fifteen minutes, then smiled and said to myself: so that's why they didn't give me anything to read. Then my mind started to work again, thank goodness. If a little learning could ever be a dangerous thing, I had encountered a classic example. Attitude clearly matters in fighting cancer. We don't know why (from my old-style materialistic perspective, I suspect that mental states feed back upon the immune system). But match people with the same cancer for age, class, health, socioeconomic status, and, in general, those with positive attitudes, with a strong will and purpose for living, with commitment to struggle, with an active response to aiding their own treatment and not just a passive acceptance of anything doctors say, tend to live longer. A few months later I asked Sir Peter Medawar, my personal scientific guru and a Nobelist in immunology, what the best prescription for success against cancer might be. "A sanguine personality," he replied. Fortunately (since one can't reconstruct oneself at short notice and for a definite purpose), I am, if anything, even-tempered and confident in just this manner. Hence the dilemma for humane doctors: since attitude matters so critically, should such a sombre conclusion be advertised, especially since few people have sufficient understanding of statistics to evaluate what the statements really mean? From years of experience with the small-scale evolution of Bahamian land snails treated quantitatively, I have developed this technical knowledge - and I am convinced that it played a major role in saving my life. Knowledge is indeed power, in Bacon's proverb. The problem may be briefly stated: What does "median mortality of eight months" signify in our vernacular? I suspect that most people, without training in statistics, would read such a statement as "I will probably be dead in eight months" - the very conclusion that must be avoided, since it isn't so, and since attitude matters so much. I was not, of course, overjoyed, but I didn't read the statement in this vernacular way either. My technical training enjoined a different perspective on "eight months median mortality." The point is a subtle one, but profound - for it embodies the distinctive way of thinking in my own field of evolutionary biology and natural history. We still carry the historical baggage of a Platonic heritage that seeks sharp essences and definite boundaries. (Thus we hope to find an unambiguous "beginning of life" or "definition of death," although nature often comes to us as irreducible continua.) This Platonic heritage, with its emphasis in clear distinctions and separated immutable entities, leads us to view statistical measures of central tendency wrongly, indeed opposite to the appropriate interpretation in our actual world of variation, shadings, and continua. In short, we view means and medians as the hard "realities," and the variation that permits their calculation as a set of transient and imperfect measurements of this hidden essence. If the median is the reality and variation around the median just a device for its calculation, the "I will probably be dead in eight months" may pass as a reasonable interpretation. But all evolutionary biologists know that variation itself is nature's only irreducible essence. Variation is the hard reality, not a set of imperfect measures for a central tendency. Means and medians are the abstractions. Therefore, I looked at the mesothelioma statistics quite differently - and not only because I am an optimist who tends to see the doughnut instead of the hole, but primarily because I know that variation itself is the reality. I had to place myself amidst the variation. When I learned about the eight-month median, my first intellectual reaction was: fine, half the people will live longer; now what are my chances of being in that half. I read for a furious and nervous hour and concluded, with relief: damned good. I possessed every one of the characteristics conferring a probability of longer life: I was young; my disease had been recognized in a relatively early stage; I would receive the nation's best medical treatment; I had the world to live for; I knew how to read the data properly and not despair. Another technical point then added even more solace. I immediately recognized that the distribution of variation about the eight-month median would almost surely be what statisticians call "right skewed." (In a symmetrical distribution, the profile of variation to the left of the central tendency is a mirror image of variation to the right. In skewed distributions, variation to one side of the central tendency is more stretched out - left skewed if extended to the left, right skewed if stretched out to the right.) The distribution of variation had to be right skewed, I reasoned. After all, the left of the distribution contains an irrevocable lower boundary of zero (since mesothelioma can only be identified at death or before). Thus, there isn't much room for the distribution's lower (or left) half - it must be scrunched up between zero and eight months. But the upper (or right) half can extend out for years and years, even if nobody ultimately survives. The distribution must be right skewed, and I needed to know how long the extended tail ran - for I had already concluded that my favorable profile made me a good candidate for that part of the curve. The distribution was indeed, strongly right skewed, with a long tail (however small) that extended for several years above the eight month median. I saw no reason why I shouldn't be in that small tail, and I breathed a very long sigh of relief. My technical knowledge had helped. I had read the graph correctly. I had asked the right question and found the answers. I had obtained, in all probability, the most precious of all possible gifts in the circumstances - substantial time. I didn't have to stop and immediately follow Isaiah's injunction to Hezekiah - set thine house in order for thou shalt die, and not live. I would have time to think, to plan, and to fight. One final point about statistical distributions. They apply only to a prescribed set of circumstances - in this case to survival with mesothelioma under conventional modes of treatment. If circumstances change, the distribution may alter. I was placed on an experimental protocol of treatment and, if fortune holds, will be in the first cohort of a new distribution with high median and a right tail extending to death by natural causes at advanced old age. It has become, in my view, a bit too trendy to regard the acceptance of death as something tantamount to intrinsic dignity. Of course I agree with the preacher of Ecclesiastes that there is a time to love and a time to die - and when my skein runs out I hope to face the end calmly and in my own way. For most situations, however, I prefer the more martial view that death is the ultimate enemy - and I find nothing reproachable in those who rage mightily against the dying of the light. The swords of battle are numerous, and none more effective than humor. My death was announced at a meeting of my colleagues in Scotland, and I almost experienced the delicious pleasure of reading my obituary penned by one of my best friends (the so-and-so got suspicious and checked; he too is a statistician, and didn't expect to find me so far out on the right tail). Still, the incident provided my first good laugh after the diagnosis. Just think, I almost got to repeat Mark Twain's most famous line of all: the reports of my death are greatly exaggerated. ----------------------------- Dr. Gould was one of my favorite twentieth century scientific essayist. He penned this in 1982, and though it was cancer that took him from us in 2002, it was not the cancer he discusses here. this essay is [[all over the web|https://csn.cancer.org/node/213889]], so I consider it to be part of the public domain.
The most exciting phrase to hear in science, the one that heralds new discoveries, is not "Eureka!", but "That's funny...".
The book "The Most Human Human" by Brian Christian opens with the following anecdote:
>[[Claude Shannon|https://en.wikipedia.org/wiki/Claude_Shannon]], artificial intelligence pioneer and founder of information theory, met his wife, Mary Elizabeth, at work. This was Bell Labs in Murray Hill, New Jersey, the early 1940s. He was an engineer, working on wartime cryptography and signal transmission.
>She was a computer^^1^^.
The book starts with Christian describing why and how he became a human "confederate" in the 2009 [[''Turing Test''|https://plato.stanford.edu/entries/turing-test/]] event, which he explains:
>Each year, the artificial intelligence (AI) community convenes for the field's most anticipated and controversial annual event -- a competition called the Turing test. The test is named for British mathematician Alan Turing, one of the founders of computer science, who in 1950 attempted to answer one of the field's earliest questions: Can machines think? That is, would it ever be possible to construct a computer so sophisticated that it could actually be said to be thinking, to be intelligent, to have a mind? And if indeed there were, someday such a machine: How would we know?
>
>Instead of debating this question on purely theoretical grounds, Turing proposed an experiment. A panel of judges poses questions by computer terminal to a pair of unseen correspondents, one a human “confederate," the other a computer program, and attempts to discern which is which. There are no restrictions on what can be said: the dialogue can range from small talk to the facts of the world (e.g., how many legs ants have, what country Paris is in) to celebrity gossip and heavy-duty philosophy—the whole gamut of human conversation.
>Turing predicted that by the year 2000, computers would be able to fool 30 percent of human judges after five minutes of conversation, and that as a result “one will be able to speak of machines thinking without expecting to be contradicted.”
>
>Turing's prediction has not come to pass; at the 2008 contest, however, held in Reading, England, the top program came up shy of that mark by just a single vote. The 2009 test in Brighton could be the decisive one.
>
>And I am participating in it, as one of four human confederates going head-to-head (head-to-motherboard?) against the top AI programs. In each of several rounds, I, along with the other confederates, will be paired off with an AI program and a judge - and will have the task of convincing the latter that I am, in fact, human.
and he adds:
>Fortunately, I //am// human; unfortunately, it's not clear how much that will help.
(See/compare to a [[reverse Turing Test|The Gnirut Test - by Charles Platt]]).
As for the title of the book:
Each year, the AI program which "fools" the judges and gets the most votes is awarded the title "The Most Human Computer". It is the title (and the prize) which the participating Computer Science research teams (an all spectators) are principally interested in.
But, intriguingly, there is another title given out, this one to the //confederate// who got the most votes from the judges: "The Most Human Human".
Christian writes that when he read that in 2008 an AI program almost made it and almost passed the Turing Test, and that 2009 might be the year machines finally pass the threshold, he was determined and resolved: //Not on my watch//.
Christian refers to the famous [[chess competition between the Chess Master Garry Casparov and IBM's Deep Blue computer|The end of an era, the beginning of another? HAL, Deep Blue and Kasparov]] [[held in 1996|https://en.wikipedia.org/wiki/Deep_Blue_versus_Garry_Kasparov]] as another (romantic) attempt to "defend the human race". (see also [[History of the chess table]]).
In another reference to history, Christian writes:
> In the mid-twentieth century, a piece of cutting-edge mathematical gadgetry was "like a computer." (referring to a person/occupation^^1^^).
> In the twenty-first century, it is the //human// math whiz that is "like a computer". (referring to the machine).
> An odd twist: we're //like// the thing that used to be like us. We imitate our old imitators, one of the strange reversals of fortune in the long saga of human uniqueness.
And ''on human uniqueness (of character)'':
>My mind goes back to the organizers' advice to "just be myself", to how much philosophers have agonized over this idea. While other existentialists—for instance, Jean-Paul Sartre emphasized authenticity and originality and freedom from outside influence, nineteenth-century German philosopher Friedrich Nietzsche held the startling opinion that the most important part of "being oneself" was—in Brown University philosopher Bernard Reginster's words—"being one self, any self."
>Nietzsche spoke of this as “giving style to one's character," comparing people to works of art, which we often judge according to their “concinnity," [the skillful and harmonious arrangement or fitting together of the different parts] the way their parts fit together to make a whole: "In the end, when the work is finished, it becomes evident how the constraint of a single taste governed and formed everything large and small.”
>Computer culture critics like Jaron Lanier are skeptical, for instance, of decentralized projects like Wikipedia, arguing:
>>The Sims, ... the iPhone, the Pixar movies, and all the other beloved successes of digital culture ... are personal expressions. True, they often involve large groups of collaborators, but there is always a central personal vision—a Will Wright, a Steve Jobs, or a Brad Bird conceiving the vision and directing a team of people earning salaries.
>>It is this same "central personal vision" that is crucial for Nietzsche, who goes so far as to say, "Whether this taste was good or bad is less important than one might suppose, if only it was a single taste!"
I can't say that I fully agree with Lanier. He is right that consistency of behavior, style, User Interface, etc., are important in good apps and products, and a "guiding principle" is necessary to achieve that, it doesn't have to be a "single hand" that does it, and I believe that "distributed" organizations and structures will become more popular and effective in the future.
>It is precisely the “central personal vision” of Lanier and “single taste" of Nietzsche that is lacking in most chatbots. For instance, I had the following conversation with “Joan,” the Cleverbot-offshoot program that won the Loebner Prize in 2006. Though each of her answers, taken separately, is perfectly sensible and human, their sum produces nothing but a hilarious cacophony in the way of identity.
>There is a central trade-off in the world of bot programming, between coherence of the program's personality or style and the range of its responses. By "crowdsourcing" the task of writing a program's responses to the users themselves, the program acquires an explosive growth in its behaviors, but these behaviors stop being internally consistent.
I have to say, that I'm sure this issue will be resolved with more/future work on AI and neurobiology/psychology, and our understanding of the mind/consciousness.
Christian points out that in the evolution of computers, the first area successfully tackled and resolved (in the sense that it supersedes human capabilities) is calculation and logic operations:
>Descartes, in the seventeenth century, picks up these threads [about thought, logic, reason, experience, senses, etc.) and leverages the mistrust of the senses toward a kind of radical skepticism: How do I know my hands are really in front of me? How do I know the world actually exists? How do I know that I exist?
>His answer becomes the most famous sentence in all of philosophy. Cogito ergo sum. I think, therefore I am.
>I think, therefore I am—not “I register the world” (as Epicurus might have put it), or "I experience," or "I feel,” or “I desire,” or “I recognize," or "I sense.” No. I think. The capacity furthest away from lived reality is that which assures us of lived reality—at least, so says Descartes.
>This is one of the most interesting subplots, and ironies, in the story of AI, because it was deductive logic, a field that Aristotle helped invent, that was the very first domino to fall.^^2^^
>[Alan Turing's and Claude Shannon's work...] ends up amounting to a huge blow to humans' unique claim to and dominance of the area of "reasoning". Computers, lacking almost everything else that makes humans humans, have our //unique// piece in spades. They have more of this than we do.
----
^^1^^ - an explanation, just in case: a "computer" in the pre-~Computer-Science days (and as early as the 17^^th^^ century) meant "a person who computes": one performing mathematical calculations, before electronic computers became commercially available. Later, in the early computer days, computing had been a branch of Math Departments, and Human Computers, as they were called, were people – often women – who used and operated these machines to find mathematical solutions via carefully crafted procedures, what we call programming today.
^^2^^ this is another example of an "unforeseen path", where humans solved a problem ("creating (digital) 'computers' ") in a way that is very different from how nature solved it ("creating (human) 'computers' "). Other examples of entirely different solutions are "creating human flight" (and how airplanes fly vs. how birds fly), "enabling human locomotion" (e.g., wheels vs. feet).
In computer programming: The most secure, the fastest, and the most maintainable code (by far :) is the code not written (or not needed). or as Ken Thompson had said: > You don't have to optimize what you don't write. The most powerful optimization tool in existence may be the delete key. One of my most productive days was throwing away 1000 lines of code. (see the [[story about program and programmer productivity|Measuring the Right Thing (software effectiveness metric)]]).
from Jim Holt's "Why Does the World Exist?: An Existential Detective Story", in an interview with John Updike (see [[Richard Hamming's thoughts|Perhaps there are thoughts we cannot think]] for a related perspective) >[T]he laws amount to a funny way of saying, Nothing equals something, Updike said, bursting into laughter. QED! One opinion I ve encountered is that, since getting from nothing to something involves time, and time didn't exist before there was something, the whole question is a meaningless one that we should stop asking ourselves. It's beyond our intellectual limits as a species. Put yourself into the position of a dog. A dog is responsive, shows intuition, looks at us with eyes behind which there is intelligence of a sort, and yet a dog must not understand most of the things it sees people doing. It must have no idea how they invented, say, the internal-combustion engine. So maybe what we need to do is imagine that we re dogs and that there are realms that go beyond our understanding. I m not sure I buy that view, but it is a way of saying that the mystery of being is a permanent mystery, at least given the present state of the human brain. I have trouble even believing and this will offend you the standard scientific explanation of how the universe rapidly grew from nearly nothing. Just think of it. The notion that this planet and all the stars we see, and many thousands of times more than those we see that all this was once bounded in a point with the size of, what, a period or a grape? How, I ask myself, could that possibly be? And, that said, I sort of move on. And yet, I don't see this as a disheartening or deflating viewpoint, but potentially a statement of a natural fact, which at the minimum should help us focus on pursuing and asking questions that have a promise to be more fruitful. So, it can be viewed as a "focusing lens" of sorts. And it seems like I'm not alone in this. As Isaac Asimov said: >The most beautiful experience we can have is the mysterious the fundamental emotion which stands at the cradle of true art and true science. which to me is a very powerful driver to be engaged in science! And it's an on-going (lifelong, spiraling) effort/path!
In a short essay titled [["The Nature of Information"|http://www.deewhock.com/essays/the-nature-of-information]], [[Dee Hock|http://www.deewhock.com/#intro]] (CEO of Visa) makes some excellent and thoughtful points about the nature and impact of information on what he calls "The Age of Mind Crafting" (as opposed to "The Age of Hand Crafting" (preindustrial revolution) and "The Age of Machine crafting" (post-industrial revolution)). About the nature of information as opposed to other resources we know and use: >Unlike finite physical resources, information is not depleted by use. Information transmitted is gain to the recipient but is no loss to the source. Information can be utilized by everyone without loss to anyone. As far as we know, the supply of information is infinite, therefore, it does not obey any of our industrial age concepts or laws of scarcity. It obeys only concepts and principles of infinite abundance, infinite utilization, and infinite recombination. About our misconception (and misbehavior) regarding information and its handling: >Projecting onto information our old notions of property, thus turning it into a method by which one person can extract wealth from another, neither reveals nor changes the extraordinary nature of information. It reveals only the limited nature of man; of his lack of awareness of his internal model of reality; of his reluctance to change it when awareness of it dawns; of the degree to which it shapes beliefs and external behavior. About some of the things information affords: >Information is a miser of energy. It can endlessly replicate, move ubiquitously at the speed of light, and massively condense in minute space, all at minuscule expense of energy, in other words, cost. In countless ways, it is becoming a replacement for our present enormously wasteful use of matter. To the extent that we increase the value of the mental content of goods and services, we can reduce the value of the physical content. We can make them lighter, more durable, more recyclable, more versatile and more transportable. And more about information's nature and its implications to us: >Information breeds. When one bit of information is combined with another, the result is new information. Information knows no boundaries. It cannot be contained. No matter what constraints we try to put on information, it will become the slave and property of no one. Efforts to make information conform to archaic notions of scarcity, ownership and finite physical quantity – concepts that grew out of the agricultural and industrial age – merely lock mankind into old, mental boxes of constraint and exploitation. Information is ethically neutral. Its immense power is as applicable to destructive, inequitable, violent ends as it is to constructive, equitable, peaceful ends. About how most of us don't understand the deep shifts that an information-rich environment creates: >Thinking about a society based on information and one based on physicality requires radically different perspective and consciousness. We too often prefer to ignore the fundamental differences and carry over into the Age of Mind Crafting ideas, values, concepts and assumptions which proved useful in the Age of Machine Crafting -- concepts such as ownership, finite supply, obsolescence, loss by conveyance, containment, scarcity, separability, quantifiable measurement, and command-and-control management. About the shift we need to make in light of the nature of information: >Products, services and organizations in which the value of the mental content begins to dwarf the value of the physical content require wise people of deep understanding. To endlessly add to the quantity of mechanistic information, knowledge and technology without similar evolution of values and wisdom is not only foolish, it is dangerous. To massively develop means and act in accordance with what those means permit, without careful consideration of ends in the context of values is a grossly foolish misuse of information. > >The emergence of this new age based on information, whatever we choose to label it, calls into question virtually every concept of societal organization, management and conduct on which we have come to rely. Clinging too rigorously to old concepts, dismissing new concepts too lightly, protecting old forms which resulted from those concepts too fiercely, imposing those forms on a changing society too resolutely, are a certain path to failure.
Dick's one sentence definition: Reality is that which, when you stop believing in it, doesn’t go away. The nature of reality as Dick sees it is [[discussed more in BrainPickings|https://www.brainpickings.org/2013/09/06/how-to-build-a-universe-philip-k-dick/]], covering his //How to Build a Universe//. [[Dick's full speech|http://deoxy.org/pkd_how2build.htm]] In the speech he gives a synopsis of one of his stories (the first?) where he writes about a perspective of a dog, with possibly strong implications about our (i.e., human) perception/view of reality: >My first story had to do with a dog who imagined that the garbagemen who came every Friday morning were stealing valuable food which the family had carefully stored away in a safe metal container. Every day, members of the family carried out paper sacks of nice ripe food, stuffed them into the metal container, shut the lid tightly—and when the container was full, these dreadful-looking creatures came and stole everything but the can. > >Finally, in the story, the dog begins to imagine that someday the garbagemen will eat the people in the house, as well as stealing their food. Of course, the dog is wrong about this. We all know that garbagemen do not eat people. But the dog's extrapolation was in a sense logical—given the facts at his disposal. The story was about a real dog, and I used to watch him and try to get inside his head and imagine how he saw the world. Certainly, I decided, that dog sees the world quite differently than I do, or any humans do. This is echoed by what astrophysicist and philosopher Marcelo Gleiser examines in //The Island of Knowledge: The Limits of Science and the Search for Meaning//, (([[discussed in BrainPickings|https://www.brainpickings.org/2015/02/02/the-island-of-knowledge-marcelo-gleiser/]]) where he writes: >What we see of the world is only a sliver of what’s “out there.” There is much that is invisible to the eye, even when we augment our sensorial perception with telescopes, microscopes, and other tools of exploration. Like our senses, every instrument has a range. Because much of Nature remains hidden from us, our view of the world is based only on the fraction of reality that we can measure and analyze. Science, as our narrative describing what we see and what we conjecture exists in the natural world, is thus necessarily limited, telling only part of the story… We strive toward knowledge, always more knowledge, but must understand that we are, and will remain, surrounded by mystery… It is the flirting with this mystery, the urge to go beyond the boundaries of the known, that feeds our creative impulse, that makes us want to know more. Gleiser adds: >If large portions of the world remain unseen or inaccessible to us, we must consider the meaning of the word “reality” with great care. We must consider whether there is such a thing as an “ultimate reality” out there — the final substrate of all there is — and, if so, whether we can ever hope to grasp it in its totality^^1^^. which I think echoes what Carl Sagan had to say about knowledge of reality (in his masterwork [[Varieties of Scientific Experience|https://www.brainpickings.org/2013/12/20/carl-sagan-varieties-of-scientific-experience/]]): >If we ever reach the point where we think we thoroughly understand who we are and where we came from, we will have failed. In other words (I think), they both say that if we ever end up thinking that we "got it", we really (ha!) did not get it. But, he doesn't see it necessarily as "bad news", but rather as an encouragement to keep striving, creating, inventing, forever: >This realization should open doors, not close them, since it makes the search for knowledge an open-ended pursuit, an endless romance with the unknown. For examples of how applying the scientific method/view may be actually misleading or distorting reality see [[The Scientific Bubble]] (and also [[Minding the obvious]]). In the last chapter of the book, Gleiser positions science in the context of our humanness: > To accept the incompleteness of knowledge is not a defeat of the human intelect; it doesn't mean we are throwing in the towel, surrendering. It means that we are placing science within the human realm, fallible even if powerful, incomplete even if the best tool we have for describing the world. Science is not a reflection of a God-given truth, made of discoveries plucked from a perfect Platonic realm; science is a reflection of our very human disquietude, of our longing for order and control, of our awe and fear at the immensity of the cosmos. And, human nature (or Nature's nature) is such, that we always live in our bubble, scientific //and// otherwise, regardless. We always experience life and the world through our filters. As the poet Edward Young wrote in [[Night Thoughts|https://www.gutenberg.org/files/33156/33156-h/33156-h.htm]] (published 1742): >In senses, which inherit earth, and heavens; >Enjoy the various riches Nature yields; >Far nobler! give the riches they enjoy; >Give taste to fruits; and harmony to groves; >Their radiant beams to gold, and gold’s bright fire; >Take in, at once, the landscape of the world, >At a small inlet, which a grain might close, >And half create the wondrous world they see. >Our senses, as our reason, are divine. >But for the magic organ’s powerful charm, >Earth were a rude, uncolour’d chaos still. >Objects are but th’ occasion; ours th’ exploit; >Ours is the cloth, the pencil, and the paint, >Which nature’s admirable picture draws; >And beautifies creation’s ample dome. ---- Note: for another perspective on the nature of reality see Nick Bostrom's [[Are you living in a computer simulation?]] ^^1^^ Nothing new under the sun? see [[Sallustius]]'s take on [[the nature of reality|One may call the world a myth, in which bodies and things are visible, but souls and minds hidden...]]
From an article titled [["The Newell Test for a theory of cognition"|https://stanford.edu/~jlmcc/papers/AndersonLebiere03.pdf]] by John Anderson (of [[ACT-R|http://act-r.psy.cmu.edu/about/]] fame; at Carnegie Mellon). >Newell (1980; 1990) proposed that cognitive theories be developed in an effort to satisfy multiple criteria and provided a list of 12 criteria that the human cognitive architecture would have to satisfy in order to be functional: flexible behavior, real-time performance, adaptive behavior, vast knowledge base,dynamic behavior, knowledge integration, natural language, learning, development, evolution, and brain realization. A short summary of these criteria: 1. Behave as an (almost) arbitrary function of the environment–Is it computationally universal with failure? 2. Operate in real time–Given its timing assumptions, can it respond as fast as humans? 3. Exhibit rational, that is, effective adaptive behavior–Does the system yield functional behavior in the real world? 4. Use vast amounts of knowledge about the environment–How does the size of the knowledge base affect performance? 5. Behave robustly in the face of error, the unexpected, and theunknown–Can it produce cognitive agents that successfully inhabit dynamic environments? 6. Integrate diverse knowledge–Is it capable of common examples of intellectual combination? 7. Use (natural) language–Is it ready to take a test of language proficiency? 8. Exhibit self-awareness and a sense of self–Can it produce functional accounts of phenomena that re-reflect consciousness? 9. Learn from its environment–Can it produce the variety of human learning? 10. Acquire capabilities through development–Can it account for developmental phenomena? 11. Arise through evolution–Does the theory relate to evolutionary and comparative considerations? 12. Be realizable within the brain–Do the components of the theory exhaustively map ontobrain processes?
From the book //Sailing home: Using the wisdom of Homer's Odyssey to navigate life's perils and pitfalls// by Norman Fischer: >Like the experience of deja-vu (Haven't I already been here?), journeys of return are uncanny and paradoxical. We start from home, and we return home, coming full circle. One might well wonder, What's the point of such a journey? Why leave, in the first place, if you are only going to come back to where you started from? But there is a point to this arduous and circular wandering. True, we do come back to our starting point, and we return with nothing we didn't already have before we left. Yet, at the same time there is an important difference: we are different, and our appreciation of what our life is and has always been is deeper. Click the image below to see Spiraling Discovery in action (10MB .mov) [img[Click to see Spiraling Discovery in action|resources/escher_gallery_1.jpg][ resources/escher_print_gallery_loop_1.mpg]] [[Escher's Print Gallery]] And as [[Sir Terry Pratchett had said|http://www.chrisjoneswriting.com/terry-pratchett-quotes/category/travel]]: >Why do you go away? So that you can come back. So that you can see the place you came from with new eyes and extra colours. And the people there see you differently, too. Coming back to where you started is not the same as never leaving.
This is a very [[short piece by Alison Gopnik which appeared in the WSJ|http://alisongopnik.com/Alison_Gopnik_WSJcolumns.htm#21Mar14]] talking about both the potential and the dangers of "New Technology" :) I think that she makes an excellent point about the fact that we probably currently experience "echoes of a recurring theme" in human history (similar to examples like [["the dangers and evilness" of speeding cars|https://www.detroitnews.com/story/news/local/michigan-history/2015/04/26/auto-traffic-history-detroit/26312107/]] (or trains, or airplanes ... you get the picture :), and the fact that while there are (and will always be) dangers and negative effects to adopting new technology, it would be a mistake (in my opinion :) to "throw the baby with the bathwater" (if even possible). Gopnik also wrote [[a chapter about it|pg. 271 - ALISON GOPNIK: Incomprehensible Visitors from the Technological Future]] in the book [[Is the Internet Changing the Way You Think?]] So here it is: THE KID WHO WOULDN'T LET GO OF 'THE DEVICE' How does technology reshape our children’s minds and brains? Here is a disturbing story from the near future. They gave her The Device when she was only two. It worked through a powerful and sophisticated optic nerve brain-mind interface, injecting it’s content into her cortex. By the time she was five, she would immediately be swept away into the alternate universe that the device created. Throughout her childhood, she would become entirely oblivious to her surroundings in its grip, for hours at a time. She would surreptitiously hide it under her desk at school, and reach for it immediately as soon as she got home. By adolescence, the images of the device – a girl entering a ballroom, a man dying on a battlefield – were more vivid to her than her own memories. As a grown woman her addiction to The Device continued. It dominated every room of her house, even the bathroom. Its images filled her head even when she made love. When she travelled, her first thought was to be sure that she had access to The Device and she was filled with panic at the thought that she would have to spend a day without it. When her child broke his arm, she paused to make sure that The Device would be with her in the emergency room. Even sadder, as soon as her children were old enough she did her very best to connect them to The Device, too. The psychologists and neuroscientists showed just how powerful The Device had become. Psychological studies showed that its users literally could not avoid entering its world, the second they made contact their brains automatically and involuntarily engaged with it. More, large portions of their brains that had originally been designed for other purposes had been hijacked to the exclusive service of The Device. Well, anyway, I hope that this is a story of the near future. It certainly is a story of the near past. The Device, you see, is the printed book^^1^^, and the story is my autobiography. [[Socrates was the first to raise the alarm about this powerful new technology|Why writing (and the computer :) is a 'dangerous technology']] – he argued, presciently, that the rise of reading would destroy the old arts of memory and discussion. The latest Device to interface with my retina is “Its Complicated: The Social Networked Life of Teens” by Danah Boyd at NYU and Microsoft Research. Digital social network technologies play as large a role in the lives of current children as books once did for me. Boyd spent thousands of hours with teenagers from many different backgrounds, observing the way they use technology and talking to them about what technology meant to them. Her conclusion is that young people use social media to do what they have always done – establish a community of friends and peers, distance themselves from their parents, flirt and gossip, bully, experiment, rebel. At the same time, she argues that the technology does make a difference, just as the book, the printing press and the telegraph did. An ugly taunt that once dissolved in the fetid locker-room air can travel across the world in a moment, and linger forever. Teenagers must learn to reckon with and navigate those new aspects of our current technologies, and for the most part that’s just what they do. Boyd thoughtfully makes the case against both the alarmists and the techtopians. The kids are all right or at least as all right as kids have ever been. So why all the worry? Perhaps it’s because of the inevitable difference between looking forward towards generational changes or looking back at them. As the parable of The Device illustrates we always look at our children’s future with equal parts unjustified alarm and unjustified hope – utopia and dystopia. We look at our own past with wistful nostalgia. It may be hard to believe but Boyd’s book suggests that someday even Facebook will be a fond memory. BTW, Hermann Hesse wrote a [[thought provoking essay about three types of readers|Hermann Hesse on Three Types of Readers]] which is relevant to this. ---- ^^1^^ - In an article titled [[Don't Touch that Dial|http://www.slate.com/articles/health_and_science/science/2010/02/dont_touch_that_dial.html]] in the Slate Magazine, Vaughan Bell opens with a similar anecdote: >A respected Swiss scientist, Conrad Gessner, might have been the first to raise the alarm about the effects of information overload. In a landmark book, he described how the modern world overwhelmed people with data and that this overabundance was both "confusing and harmful" to the mind. The media now echo his concerns with reports on the unprecedented risks of living in an "always on" digital environment. It's worth noting that Gessner, for his part, never once used e-mail and was completely ignorant about computers. That's not because he was a technophobe but because he died in 1565. His warnings referred to the seemingly unmanageable flood of information unleashed by the printing press.
Andrea diSessa, [[in his book "Changing Minds")|resources/diSessa - Changing Minds - Chapter1.pdf]] gives an example of the __power of literacy__ to change the way we think: One example is the Calculus, a new notation (Newton, Leibniz) that forever changed not only what we think but also how we think about change (infinitesimal deltas) and rations of changes. And not only did it change how we are thinking, but also who and when: nowadays, high school students can think and express their thinking in ways that very sharp scientists (Galileo comes to mind) could not in the past. [[Another example diSessa gives|Examples of the power of math notation]] is how it takes Galileo several pages of text to describe his idea about rates of changes staying constant (in a free fall, related to his experiment at the Tower of Pisa), and the fact that nowadays, a high school student can express the //same ideas// in a few lines of "very simple" (high school) math. It seems to me that the fact that a genius like Galileo had to struggle through pages of explanations in order to make //his ideas and way of thinking// clear (to himself and others), and something today a high school kid can both grasp, express, and use, shows us that "external intelligence amplifiers" can and do change the way we think. And if Computation in general (and the Internet in particular) cannot serve as such an "amplifier", what can?
Raymund Smullyan, in a delightful piece called [[Planet without Laughter|https://www-cs-faculty.stanford.edu/~knuth/smullyan.html]] writes about the power of ideas to make (or break) or worldview, in a way similar to how [[Barry Schwartz talks about "Idea Technology"|Barry Schwartz on Idea Technology]]. In this somewhat tongue-in-cheek parable, Smullyan touches on multiple topics (e.g., the nature of humor, spirituality, belief, ideas, morality) and gives an example of the impact of a "powerful idea", like ''free will'' on our worldview. He does this in the context of a biblical story, specifically the story of Adam and Eve in the Garden of Eden (in Smullyan's parable called "The Garden of Laughter"): > And so they [Adam and Eve] spent their days in this paradise for many years, until one day a strange green animal, something like a rat and something like a skunk, with mean, small, close-set eyes, came into the garden. This animal perceived the bliss of the couple and waxed mighty jealous. He said, "I will soon do something about that!" and sure enough he did! He approached the couple and said: >[... Why is God keeping you (Adam and Eve) in this state of "childish innocence"?] What is He afraid of? What is He hiding from you? Why does He pretend to be your friend when He is the very one who is deceiving you and who is preventing you from being true to yourselves and fulfilling your real destinies in the universe? Why do you tolerate this? There is one chink in the Lord's armor by which you can save yourselves. The Lord has given you ''free will'', by which you can oppose Him. You can put a stop to this situation; it is up to you! Only by your own efforts can you prevent the Lord from keeping you in bondage forever. And thus, the seed of a powerful idea was planted. >[...T]he idea that they could choose was a stunning novelty. It gave them an exhilarating sense of power. They of their own free will could now do things! In particular, they could, if they chose, amount to something. The question then arose: Should they amount to something? This notion of "should" was also quite new. Formerly, since they had felt that they were merely part of the stream of life rather than actively living it, ethical notions of "should," "ought," "duty," etc., had absolutely no meaning for them. But now they knew better. The troubling question arose: Was it right or wrong for them to sit by idly enjoying life rather than going out and amounting to something? From there is was only "natural" to start "connecting dots" (we humans are good at that :): >Adam and Eve also for the first time began philosophizing. They believed the Animal was right in telling them that they had free will. But the question which most puzzled them was whether they had really had free will before the Animal informed them of the fact. If they formerly had free will, they certainly had not known that they had. And is it possible to be free without knowing that one is free? In other words, was it really true, as the Animal had said, that God had already given them free will, or was it the Animal himself who caused them to have free will? It seemed likely to them that having free will is really no different from believing that one has free will. And a dialog with The Animal started the process of "bootstrapping" this idea of free will: >[The Animal said: "] And you too can have free will if you choose to." >This answer puzzled them terribly! They replied: "What? You say we can choose to have free will? You mean that having free will is a matter of choice?" >The Animal replied, "Of course it is." >Eve then protested, "But I thought you told us that God has already given us free will." >The Animal replied: "In a sense He has, but only in a passive rather than an active sense. God has, so to speak, given you the potentiality of having free will. Whether you actualize it or not is up to you. God has given you the ability to make choices; He does not force you to make them. You can use your free will only if you choose to." > Adam answered, "But if we can choose to, that means we already do have free will." >The Animal replied, "Yes, it is in that sense that God has given you free will." And Smullyan adds: "And thus the sciences of metaphysics and epistemology were born." But similar to the role and power of science, free will is not necessarily the "downfall" (in the sens of the biblical story and the way it portrays it). It is just a tool and a capability to choose (and do) good //or// evil. So, in Smullyan's fable, Adam and Eve reached a conclusion: >[They] debated this for many weeks, and finally decided to remain in the garden and not to amount to something. They decided to trust the Lord and not the Evil Animal. Yes, they finally realized, the Lord is their friend and the Animal their foe. And so one day the Animal came into the garden and Adam said: >"You have taught us many wonderful things. You have taught us that we have free will. Whether you have taught us this, or whether by some mysterious power you have caused us to have free will, or whether it was God who 'allowed' us to have free will, or whether He 'made us' have free will, or whether it is we who have 'chosen' to have free will, we do not know. We do not understand the phenomenon of free will, but we now know that whatever it really is, we certainly have it. Perhaps we have chosen to have it; we really don't know. All we now know for sure is that we in fact do have it. And you are absolutely right that we can now use our free will to reject the Lord and His ways. Yes, we are indeed free to do this. >But do you not realize that by the very same token we are now free to reject you? Yes, we now have the power to reject you or the Lord. And it is you we have decided to reject! Of our own free wills we thoroughly cast you out of our minds and hearts. We reject you and your ways. We will no longer heed you or your words. We cast you out of this very garden. This garden is our property; the Lord has given it to us, not to you! It is our own private property, and you can no longer be here without our permission. We have so far suffered you here only as a guest. But you are no longer a welcome guest. Begone from the Garden, and don't you ever dare return. If we ever find you here again, we will kill you." >The Animal departed without a word, and never returned. But, as Oliver Wendell Holmes had said: >Man's mind, once stretched by a new idea, never regains its original dimensions. And so the the Animal's idea that Adam and Eve "should amount to something" got stuck in their minds and did not let go (hence, a "powerful idea"). And at the next (daily!) encounter with God in The Garden, they were irritable and bothered by the Anomal's ideas and God sensed it and "let them go": >[He said:"] You may as well go forth and 'amount to something,' which is what you deep down really want. Yes, you can amount to a great deal -- indeed you can beget an entire race. You will go forth and do this."
Toni Morrison [[tells a powerful tale|https://www.brainpickings.org/2016/12/07/toni-morrison-nobel-prize-speech/]] about the gift and power of human language, and the responsibility for using it well. The story is about a blind, old and wise woman who is asked (more like taunted and mocked) whether a bird being held in someones hands in dead or alive. Morrison parallels the bird to language and writes: >[The old woman, who Morrison imagines as a practiced writer] thinks of language partly as a system, partly as a living thing over which one has control, but mostly as agency — as an act with consequences. >[...] she thinks of language as susceptible to death, erasure; certainly imperiled and salvageable only by an effort of the will. She believes that if the bird in the hands of her visitors is dead the custodians are responsible for the corpse. For her a dead language is not only one no longer spoken or written, it is unyielding language content to admire its own paralysis. Like statist language, censored and censoring. Ruthless in its policing duties, it has no desire or purpose other than maintaining the free range of its own narcotic narcissism, its own exclusivity and dominance. However moribund, it is not without effect for it actively thwarts the intellect, stalls conscience, suppresses human potential. Language is powerful and has a strong and undeniable effect on us, but Morrison adds: >The vitality of language lies in its ability to limn the actual, imagined and possible lives of its speakers, readers, writers. Although its poise is sometimes in displacing experience it is not a substitute for it. It arcs toward the place where meaning may lie. >[...] language can never live up to life once and for all. Nor should it. Language can never “pin down” slavery, genocide, war. Nor should it yearn for the arrogance to be able to do so. Its force, its felicity is in its reach toward the ineffable. >Be it grand or slender, burrowing, blasting, or refusing to sanctify; whether it laughs out loud or is a cry without an alphabet, the choice word, the chosen silence, unmolested language surges toward knowledge, not its destruction. And she concludes: >Word-work is sublime … because it is generative; it makes meaning that secures our difference, our human difference — the way in which we are like no other life. > >We die. That may be the meaning of life. But we do language. That may be the measure of our lives.
<<forEachTiddler
where
'tiddler.tags.contains("book-chapter") && tiddler.tags.contains("The Power of Mindful Learning")'
sortBy
'tiddler.title'>>
The process of learning through life is by no means continuous and by no means universal. If it were, age and wisdom would be perfectly correlated, and there would be no such thing as an old fool — a proposition at odds with common experience. — Speech at Oberlin College, Ohio,1958
From the [[UK Ministry for Education|https://www.gov.uk/government/publications/national-curriculum-in-england-computing-programmes-of-study/national-curriculum-in-england-computing-programmes-of-study]]: A high-quality computing education equips pupils to use computational thinking and creativity to understand and change the world. Computing has deep links with mathematics, science and design and technology, and provides insights into both natural and artificial systems. The core of computing is computer science, in which pupils are taught the principles of information and computation, how digital systems work and how to put this knowledge to use through programming. Building on this knowledge and understanding, pupils are equipped to use information technology to create programs, systems and a range of content. Computing also ensures that pupils become digitally literate – able to use, and express themselves and develop their ideas through, information and communication technology – at a level suitable for the future workplace and as active participants in a digital world.
The question of whether a computer can think is no more interesting than the question of whether a submarine can swim.
[[Alan Kay|https://en.wikipedia.org/wiki/Alan_Kay]] (a "[[CS Sage|https://en.wikipedia.org/wiki/List_of_computer_scientists]]"), at OOPSLA 1997, gave an [[insightful talk|https://www.youtube.com/watch?v=oKg1hTOQXoY]] titled "The real computer revolution hasn't happened yet" ([[the 2007 transcript|http://www.vpri.org/pdf/m2007007a_revolution.pdf]]), highlights of which I cover below.
7 years after [[Kay's talk in Pisa|http://www.vpri.org/pdf/m2007007a_revolution.pdf]], on his website, Kevin Kelly echoes a similar sentiment in an article titled [[You are not late|http://kk.org/thetechnium/you-are-not-late/]], and concludes:
>So, the truth: Right now, today, in 2014 is the best time to start something on the internet. There has never been a better time in the whole history of the world to invent something. There has never been a better time with more opportunities, more openings, lower barriers, higher benefit/risk ratios, better returns, greater upside, than now. Right now, this minute. This is the time that folks in the future will look back at and say, “Oh to have been alive and well back then!”
>
>The last 30 years have created a marvelous starting point, a solid platform to build truly great things. However the coolest stuff has not been invented yet — although this new greatness will not be more of the same-same that exists today. It will not be merely “better,” it will be different, beyond, and other. But you knew that.
>
>What you may not have realized is that today truly is a wide open frontier. It is the best time EVER in human history to begin.
>
>You are not late.
So back to Kay, and a few highlights:
* The true revolutionary impact of the printing press:
> the [printing] press in the 15th century was first thought to be a less expensive automation of hand written documents, but by the 17th century its several special properties had gradually changed the way important ideas were thought about to the extent that most of the important ideas that followed and the way they were thought about had not even existed when the press was invented. The two most important ideas were the inventions of science and of new ways to organize politics in society (which, in several important cases, were themselves extensions of the scientific outlook).
* Kay makes an argument similar to [[points made by Victor Bret and Andrea diSessa|Examples of the power of math notation]] about the importance of the change in "the how" (technology), on "the what" (content, scope and extent) of what we can write and argue about, since "the how" has changed in such a revolutionary way:
> These changes in thought also changed what “literacy” meant, because literacy is not just being able to read and write, but to fluently deal with the kinds of ideas important enough to write about and discuss.
* He claims (and I agree with him :) that computers enable a new literacy, that of writing and reading simulations of arguments, phenomena, and inventions. And that this kind of literacy will be yet another big force in human evolution:
>One of the realizations we had about computers in the 60s was that they give rise to new and more powerful forms of arguments about many important issues via dynamic simulations. That is, instead of making the fairly dry claims that can be stated in prose and mathematical equations, the computer could carry out the implications of the claims to provide a better sense of whether the claims constituted a worthwhile model of reality. And, if the general literacy of the future could include the writing of these new kinds of claims and not just the consumption (reading) of them, then we would have something like the next 500 year invention after the printing press that could very likely change human thought for the better.
** This, in my opinion, is a clear and succinct way to define the new computer literacy, so I'll repeat it:
*** the (computer) literacy of the future will enable us to create/model/program ("write") and analyze/critique/consume ("read") arguments/claims/knowledge/ideas in the form of dynamic simulations "worthy" of modeling/representing aspects of reality. By "worthy" I think Kay means enabling us to think creatively, productively, usefully about new ideas and knowledge. (see also [[Prospects of Modeling]])
* He suspects that the computer revolution will take longer than anticipated by pioneers in the 1960s (like Seymour Papert, Kay himself and others):
>it looks as though the actual revolution will take longer than our optimism suggested, largely because the commercial and educational interests in the old media and modes of thought have frozen personal computing pretty much at the “imitation of paper, recordings, film and TV” level.
* It is important to teach Knowledge (content) not just processes and tools:
>The wonderful nature of modern knowledge, aided by writing and teaching, is that many ideas which require a genius to invent (in the case of calculus: two geniuses) can be learned by a much wider and less especially talented population. But it is very difficult to invent in a vacuum, even for a genius. (Imagine being born with twice Leonardo's IQ in 10,000 BC. Not a lot is going to happen! Even Leonardo couldn’t invent an engine for any of his vehicles. He was plenty smart enough but he lived in the wrong time and thus didn’t know enough.)
* Kay is not interpreting "constructing knowledge" as students/learners exploring/playing/discovering knowledge on their own. He rightfully points out that this kind of "futzing around" (my language :) rarely, if ever, creates significant (discovered) knowledge. He definitely values mentoring and guiding, and gives an example to show how ineffective/misguided the idea of just putting computers in every classroom is:
> what if we were to make an inexpensive piano and put it in every classroom? The children would certainly learn to do something with it by themselves – it could be fun, it could have really expressive elements, it would certainly be a kind of music. But it would quite miss what has been invented in music over centuries by great musicians. This would be a shame with regard to music – but for science and mathematics it ["self-guided discovery" with computers] would be a disaster.
* A powerful way to teach is
> to find ideas and representations that allow “beginners to act as intermediates”, that is, for learners to immediately start doing the actual activity in some real form.
* Kay quotes H. G. Wells saying [[Civilization is in a race between education and catastrophe.]] but modifies/clarifies it to refer more specifically to "changes in the point of view" instead of "education".
* About science and its critical role:
>The first step in science is the startling realization that “the world is not as it seems” and many adults have never taken this step but instead take the world as it seems and their inner stories as reality with often disastrous consequences. The first step is a big one, and is best taken by children. [i.e., at an early age].
>[and]
>From there, it is another giant step to include ourselves (that is, all humans) in the proper objects of study: to try to get past our stories about ourselves to understand better “what are we?” and ask “how can our flaws be mitigated?”.
And he concludes on an optimistic note:
>Though the world today is far from peaceful, there are now examples of much larger groups of people living peacefully and prospering for many more generations than ever before in history. The enlightenment of some has led to communities of outlook, knowledge, wealth, commerce, and energy that help the less enlightened behave better. It is not at all a coincidence that the first part of this real revolution in society was powered by the printing press. The next revolutions in thought – such as whole systems thinking and planning leading to major new changes in outlook – will be powered by the real computer revolution – and it could come just in time to win over catastrophe.
In a book //Equations of Eternity - Speculation on Consciousness, Meaning, and the Mathematical Rules that Orchestrate the Cosmos// by David Darling, he writes: >Classification is fundamental to survival in the real world. Unless a creature could categorize phenomena into more general types, it would have to treat every one as unique. Then the creature would have no idea what was good to eat or what represented a threat. Before it had time to establish a thing's credentials, it might be too late—the food would have gone or the predator would have struck. >One crucial fact emerges from this: the world cannot be random. If it were, it would be unpredictable. The categories that we (and other animals) recognize must be based on natural, recurring physical properties of the universe. That may seem obvious, but it is only because we are used to looking for—and finding—order, consistency, and predictability in our surroundings. (see a treatment from a Models and Analogs perspective in [[On Metaphors and Mental Models - by Patrick O’Shaughnessy]]). This echos [[Mario Livio's view, specifically on Mathematics, that invention and discovery are combined|Is Math a human invention or a series of discoveries of truths in the real world?]] in the process of humans creating their mental world. Darling continues: >Indeed, it is far from obvious, a priori, why the universe should be anything other than totally random and intractable. Randomness always seems so much easier to achieve in everyday life than organization, leave a room to its own devices and the Point seems well illustrated. How could nature, without any conscious effort, do a better job of keeping its own house in order? And yet, against all the odds, the world is patterned. And what is more, over time, these patterns have become increasingly elaborate and exquisitely organized to the extent that now the universe has created, from within its fabric, creatures of such extreme complexity that they can discern this order and classify it. Remarkably, elements of the universal classification have become capable of classifying the universe—including themselves. But this raises an important question: Do we always see objects and relationships that are really there, independent of our mental selves? How can some thing, or some class of things, or some connection between things, be said to exist without a sentient observer to perceive them? Are we not, in fact, as much inventors of the order we see as discoverers? And here Darling wonders about the same question Livio is trying to answer; basically, how come there is order out there (which we somehow perceive)? >In some curious way, the two [i.e., inventing and discovering] seem to go hand in hand. Our brains make sense of the data they perceive: they impose or invent order. And yet the basis for that perceived order must somehow already be there. It is one of the fundamental mysteries of nature, this dichotomy between what is given and what we, with our minds, create. We owe our very existence as a species to our ability to delineate patterns. We can even see patterns where none exist—the faces in a sun-lit curtain, the Greek heroes and monsters among the stars. What else might the human mind be recognizing that is not really there? And what, in any case, do we mean by "real"? And I think Livio is right when [[he states|http://www.sfu.ca/~rpyke/cafe/livio.pdf]]: >There is no doubt that the selection of topics we address mathematically has played an important role in math's perceived effectiveness. But mathematics would not work at all were there no universal features to be discovered. You may now ask: Why are there universal laws of nature at all? Or equivalently: Why is our universe governed by certain symmetries and by locality? I truly do not know the answers, except to note that perhaps in a universe without these properties, complexity and life would have never emerged, and we would not be here to ask the question.
AKA, Reactive Documents. [[Bret Victor|http://worrydream.com/]] Inspired and coined the term [[reactive documents|http://worrydream.com/ExplorableExplanations/]]. A nice (and (hopefully not for long) short and (hopefully quickly becoming) out-of-date :) [[collection of examples|http://www.maartenlambrechts.be/the-rise-of-explorable-explanations/]]. [[Chaim Gingold|http://levitylab.com/cog/]] was inspired and [[talked about|Learning through play - lessons learned from an experiential engagement designer]] how he created [[Earth Primer|http://www.earthprimer.com/]]. A [[small example|http://employees.org/~hmark/books/i4i/least_action.html]] I created with GeoGebra, based on one of Richard Feynman's Cal Tech lectures on [["The Principle of Least Action|http://www.feynmanlectures.caltech.edu/II_19.html]]". I created [[a page with several examples|http://employees.org/~hmark/books/i4i/index.html]] (some better than others :) of interactive/manipulatable educational tools/mini-environments/simulations, which I called Incubators For Intuition (I4I). This page enables the exploration of a handful of concepts like "closing the achievement gap" in education, conditional (Bayesian) probability, The principle of Least Action (Richard Feynman), The MU Puzzle (Douglas Hofstadter), The p-q Sytem (Douglas Hofstadter), and valid statistical sampling.
In a short and to the point article^^1^^ titled [[Education Isn’t Just About Churning Out ‘Skilled’ Employees|resources/Education Isnt Just About Churning Out Skilled Employees - The Experts - WSJ.htm]], Gianpiero Petriglieri is bringing up an excellent point about why we should at least pause when discussing the often heard/debated question in education circles, namely: >Companies often complain they aren’t getting graduates with the skills they need. Why is that—and what should be done about it? His point is that we, as a society, would benefit from looking and questioning the assumptions underlying this question. If we go along with the implicit assumption that the primary (only?) goal of education is to prepare learners to become good employees, we may be repeating the same scenario that formed the current education/school systems, and is catching so much criticism nowadays. One accusation is that most current schools and classrooms are the product of the need (or desire) to train students to become the workforce of the industrial revolution and 19th century society, and be "good employees". And by asking the question above, we may fall into a similar trap in the 21st century. Petriglieri rightly states: >There can be little doubt that one of the main functions of education is to support the economy by churning out skillful employees. That is not, however, its only function. The others are supporting the culture it is embedded in by churning out responsible citizens—who are not all, only, or always going to hold corporate jobs—and supporting individual students by liberating their imagination and accelerating their development. And this, I think, aligns well with the call-to-action to the educational system to "teach students to skate to where the puck will be, not to where it currently is", which [[I visually modeled|resources/skating_puck.html]] in connection to closing the achievement and opportunity gap in school and society. ---------- ^^1^^ [[The original Wall Street Journal article|http://blogs.wsj.com/experts/2013/10/09/education-isnt-just-about-churning-out-skilled-employees/]]
We all (especially in Silicon Valley) have heard about (and, if not careful, experienced) the ''Tech Bubble'', but reading the very thoughtful (and worth very slow reading) book [[Absence of Mind|http://yalebooks.co.uk/pdf/9780300145182.pdf]] by Marilynne Robinson, brought up the case of the ''Science Bubble'', which can be dangerous as well (see also [[Minding the obvious]]). I started reading Robinson's book after listening to an interesting and thought-provoking dialog between Marilynne Robinson and Marcelo Gleiser titled [[The Mystery We Are|https://soundcloud.com/onbeing/marilynne-robinson-marcelo-1]], hosted by Krista Tippett (from [[On Being|http://www.onbeing.org/]]). Robinson, who won a Pulitzer for her novel Gilead, and who is also a university lecturer and preacher, seems to be quite knowledgeable about science. In the first chapter of the book, she brings up a couple of examples of scientific overconfidence and an arrogant stance of scientists presenting scientific theories with both superiority and "moral conviction" (i.e., using terms of "right" and "wrong"), seemingly forgetting that a scientific theory, by definition, cannot be proven right (or "correct"), only wrong (or incorrect). One example is Bertrand Russell stating in the early 1920's that the religious belief in the beginning of the universe (the Genesis story) shows lack of imagination on the part of our ancestors. His view/statement was shortly "upended" by the (now accepted by the mainstream) Big Bang theory. This, in my mind, is an example of overconfidence (if not arrogance) and a misplaced conviction in the (timeless/forever-valid) "correctness" of a scientific theory. Another example is Steven Pinker's analysis of the nature of violence in human societies over the history of humanity. In his book //The Better Angels of Our Nature: Why Violence Has Declined//, he brings numerous data and statistics to demonstrate and "prove" his point (and I simplify: ) that human societies have become less violent. One of Pinker's main points is that if you look at war-related deaths over time, you see that percentage-wise they have dropped over time. As an example, in tribal warfare or religious wars the percentage of warriors killed would have been equivalent to tens of millions of people killed in a modern-day war, which thankfully has not happened in modern times. Robinson asks some very critical questions about Pinker's argument setups and conclusions. For example: in a small tribe or clan of, say, 50 people, a death of 1 or 2 people would probably be not uncommon. This is a death toll of 2-4%. She questions the validity (or meaning) of Pinker's comparison to a death toll of 2-4% of the current US population of roughly 350 million (so, 7-14 million dead). We know that this kind of massive death had happened in modern times and we also know that it is thankfully not common (unlike the 1-2 deaths in a small tribe). But is it a fair, and more importantly, meaningful, comparison? Is it teaching us something of value regarding human violence? Can we draw some helpful or meaningful conclusions from this? (think about it: in the small tribe the ''minimum'' death rate, in percent, is 2% (1 person dying in a 50 people tribe). Does it really scale in a meaningful way, i.e. can we draw meaningful conclusions about a larger population, for example in the case of 2% of the US population, which is 7 million?) This use of pure math and statistics (in this case percentages) without looking at important aspects of meaning, scaling, and so on, is an example of a Bubble, which if not distorting our perspective/view of reality, at least may be misleading. Applying science and math to try and prove a point does not necessarily make the conclusion valid and/or meaningful. Thinking this way may be a case of living in the Scientific Bubble. For a more cautious and humble scientific stance see what Marcelo Gleiser and Carl Sagan have to say in [[The nature of reality - per Philip K. Dick, Marcelo Gleiser, Carl Sagan]].
The "[[CS Sage|https://en.wikipedia.org/wiki/List_of_computer_scientists]]" [[Fred Brooks|https://en.wikipedia.org/wiki/Fred_Brooks]] (of [[The Mythical Man Month|https://archive.org/stream/mythicalmanmonth00fred/mythicalmanmonth00fred_djvu.txt]] fame), wrote a thoughtful article after receiving the //first// ACM [[Allen Newell|https://en.wikipedia.org/wiki/Allen_Newell]] Award (named after another CS Luminary/Sage) in 1994, sharing his thoughts about the [[Computer Scientist as a Toolsmith|http://www.cs.unc.edu/~brooks/Toolsmith-CACM.pdf]]. In the article he talks about "The Toolsmith as Collaborator", and observes^^1^^: >If the computer scientist is a toolsmith, and if our delight is to fashion power tools and amplifiers for minds, we must partner with those who will use our tools, those whose intelligences we hope to amplify. Let me share with you some of our experiences in interdisciplinary collaboration at Chapel Hill over the last 30 years. It has been an exciting experience, and I commend it to you as a way of working. It also has some inherent costs, which one should intentionally decide whether to pay, and some inherent pitfalls. > >''The ~Driving-Problem Approach'' >Let me begin with a paradoxical thesis: >Hitching our research to someone else’s driving problems, and solving those problems on the owners’ terms, leads us to richer computer science research. >This is a special case of the “down-is-up” paradox that governs so much of life, from marriage enrichment to career progress. >How can such a thing be so? How can working on the problems of another discipline, for the purpose of enhancing a collaborator, help me as a computer scientist? >In many ways: >• It aims us at relevant problems, not just exercises or toy-scale problems. >• It keeps us honest about success and failure, so that we don’t fool ourselves so easily. >• It makes us face the whole problem, not just the easy or mathematical parts. In computational geometry, for example, we can’t avoid the cases of collinear point triples or coplanar point quadruples. We can’t assume away ill-conditioned cases. >• Facing the whole problem in turn forces us to learn or develop new computer science, often in areas we otherwise never would have addressed. >• Besides all of that, it is just plain fun to look over the shoulders of those discovering how proteins work, or designing submarines, or fabricating on the nanometer scale. > >''The Costs of Collaboration'' >There are real costs associated with any professional collaboration, and interdisciplinary collaborations have some unique costs. I find that our teams spend about a quarter of our professional effort on routine work that supports our collaborators but does not advance our joint researches, much less the computer-science part of the research. ---- ^^1^^ See what Brooks says about [[Software creations]]
A story (with implication for teaching/teacher motivation :) Once upon a time there was an old man who used to go to the ocean to walk along the beach and enjoy the waves crashing upon the rocks. Early one morning he was walking along the shore by himself. As he looked down the deserted beach, he saw a human figure in the distance. As he got closer to the stranger, he saw that it was a young teenage boy. The boy was reaching down to the sand, picking up something and very gently throwing it into the ocean. As the old man got closer, he yelled out, "Good morning, young fellow. What are you doing?" The teenager paused, looked up and replied, "Throwing starfish back in the ocean." "Why on earth are you doing that?" asked the old man. The boy replied, "Because the sun is up and the tide is going out. If I don’t throw them in they’ll die." The old man looked at the teenager in disbelief and said, "But the beach goes on for miles and miles and there are starfish all along it. You can’t possibly make a difference." The young boy listened politely, then bent down, picked up another starfish and threw it into the sea, past the breaking waves and said, "It made a difference for that one." And then the very wise young boy continued on his way down the beach, bending down and throwing starfish after starfish back into the ocean. :: ― Loren Eiseley
From [[a series of posts by Nathan Galster on Medium|https://medium.com/@nathangalster/the-tao-of-teaching-epilogue-8672e3e7bff6]]: 1: The Way is nameless; the name is not the Way ** The wise teacher does not choose to give a particular name to her or his style of educating children. All named teaching practices have political implications, and political movements become parts of the pendulum course that education has followed throughout history. Names are limiting, for other people's definitions are attached to the names. A name can evoke unnecessary, unwarranted reactions to implied meanings that are not true of you at all. In the Tao it is important to maintain individuality. Do not follow the dictates of any one group; follow the dictates of your own, carefully developed, philosophy. 2: Silence is a virtue ** Teachers and parents who talk too much to their children often inspire resistance that may appear in the form of "tuning out,” or even as a rebellion through arguments or refusal to act. Once agreements have been made to do things a certain way, based upon shared values, teachers and students should be able to expect appropriate behaviors from one another. The wise teacher does not constantly remind the child nor does she or he criticize. Natural consequences are part of the Way. ** Do not admonish harshly or lecture repeatedly. Speak once and expect to be heard. 3: Wealth breeds competition ** In schools where the wealthy are in power, one often finds contests. Sometimes the contests are part of the explicit school culture: academic decathlons, spelling bees, top scores, best grades. Sometimes the contests are implicit: who wears the best clothes or has been to the best places, or who can give the best parties. In the Tao students who are compared with themselves and not with one another can be saved the dissension of competition. ** Allow students to enter into the process of measuring their own growth. Honor other values over wealth to help free your children and yourself to pursue a calm life together. 4: Application breeds learning; dig deeply ** Wise teachers know that they cannot “pour it in.” Children are interested learners. They enjoy finding out about new things and they are adept at memorizing certain kinds of information, as witnessed by their quick acquisition of sports statistics, lyrics to popular songs, attributes of special automobiles, or details of favorite performers' lives. When interest is high, the substance, the “stuff,” is easily retained. Positive motivation is critical in promoting deep and lasting learning. ** Similarly, the substance must be understood by the students in terms of its usefulness. The “stand and deliver” process of sharing substance can go only so far. It must be accompanied by the active participation of students in experiencing some aspects of the information and in gathering, using, and sharing the details. ** Relate learning to your students' past or present lives, or to their perceptions of the future. Students can break into groups after “teacher-talk," and share how the new information can be applied in their lives—intellectually and personally. Always be able to answer (or, better yet, demonstrate): “Why are we doing this?” 5: Be impartial ** In the Tao, all people are “straw dogs," none more important than the others. A human failing of many teachers and parents is favoritism, showing greater approval of some children than of others. Quite often the students who remind the teachers of themselves, whether accurately or not, are the ones who receive extra attention and garner extra favors. Wise teachers are aware of the many effects of cultural backgrounds, gender differences, personality types and styles of expression. ** Reach out to find points of empathy with all of your students. Encourage them all and find ways to provide equal attention with positive language and a sense of personal responsibility. 6: The Tao will never wear out with use ** Just as the mind does not wear out with use, the Way never becomes old or boring. Its essence is flexible and changing. Students and teachers grow in their human relationships together, through cooperative activities that reach for goals they have determined together. When interesting topics arise, the Tao allows for them to be explored, for the class is not inextricably bound to someone else's schedules or someone else's ideas about what must be taught at every moment. ** Over and over again, the choices that you and your students make together in respect for one another do not get old. They get better. When planning class time, simply ask the students what should be done when. 7: Do not think of self 8: Be careful with words 9: The material is fleeting, the spiritual is everlasting 10: Do not be authoritarian 11: Turn non-being into utility 12: Control input to the senses; avoid confusion and respond to inner depth 13: Love others as you love yourself; accept uncertainty 14: The Way is subtle; respect and apply the past 15: Be cautious, reserved, flexible, sincere, honest 16: Know one's own roots to embrace others 17: Have faith in others so they will have faith in you 18: When the Way is not followed or family relationships are not in harmony, hypocrisy and pious advocates arise 19: Reduce selfishness, have few desires 20: Do not see things in black and white 21: The Way is real, but elusive; intuition leads 22: Teach by example 23: Use few words 24: Progress is slow; do not boast 25: History repeats itself 26: Take your time; be attentive and receptive 27: Discipline yourself before trying to discipline others 28: Be humble; teach the wholeness of things 29: Follow the middle road; it is the heart of knowing 30: Avoid using force; don't push 31: There is no glory in victory 32: The Way cannot be mastered 33: Know yourself; the influence of virtue is immortal 34: Do not strive for greatness 35: The Way has its own rhythm; use it 36: The weak and the tender overcome the hard and the strong 37: Seek simplicity and honor what is known 38: Virtue is its own reward; differences arise when the Way is lost 39: Oneness, not fragmentation 40: Something comes from nothing; nothing comes from something 41: Appearances can deceive 42: Harmony is to be achieved through the blending of the passive and the active—the yin and the yang 43: Use your resources 44: Keep a sense of balance 45: Tranquility is more important than perfection 46: Be content with contentment 47: Cultivate inner knowledge 48: The pursuit of the Way is not like the pursuit of information 49: Regard the students' ideas with respect and treat everyone with goodness and honesty 50: A person who does not strive intensely after life nor tangle with danger can preserve life well 51: Care for others without being possessive 52: Enlightenment comes from valuing what is small 53: Do not indulge in excess 54: One who is established in the Way cannot be separated from it 55: Stay in touch with your original nature 56: It is impossible, with a person who has gained harmony, to be indifferent or intimate, to harm him or benefit him, to disgrace him or honor him 57: Succeed with encouragement, not prohibitions 58: A wise person governs in non-discriminative ways 59: Be frugal and accumulate virtue 60: A wise person will not harm others 61: In placing yourself low, you take over others 62: The Tao never rejects a bad person 63: Repay hatred with virtue, deal with the big while it is still small 64: Put things in order before disorder arises 65: Do not try to rule through cleverness 66: Do not be competitive; do not oppress 67: Have compassion, practice frugality, be willing to follow 68: Your appearance or position does not reveal your strength 69: Delight in non-confrontation 70: Be forthright and plain 71: When you don't know, say so 72: Be gentle to gain authority 73: There is victory in non-competition 74: Obey your instincts 75: Strive in moderation 76: Those who are flexible are superior 77: Excellence is its own reward 78: Be soft and weak, hard and strong 79: In attending to mistakes you may be missing an opportunity 80: Be content and find delight in your home 81: True words are not fancy; fancy words are not true
[[The thing about 998,001 is…|https://math.stackexchange.com/questions/102682/what-is-special-about-the-numbers-9801-998001-99980001]] If you divide 1,000,000 by the number 998,001, you get a list of all the three digit numbers in order except 998. Like so: [img[resources/1_div_998001.gif]]
(copied and slightly modified from Dan Meyer's blog and his [[3 act math principles|http://blog.mrmeyer.com/?p=10285]]) !!!Act One ''Introduce the central conflict of your story/task clearly, visually, viscerally, using as few words as possible.'' The visual should be clear. No (or a minimum of) words are necessary. I'm not saying anyone is going to shell out ten dollars on date night to do this math problem but you have a visceral reaction to the image. It strikes you right in the curiosity bone. Leave no one out of your first act. Your first act should impose as few demands on the students as possible either of language or of math. It should ask for little and offer a lot. This, incidentally, is as far as the #anyqs challenge takes us. !!!Act Two ''The protagonist/student overcomes obstacles, looks for resources, and develops new tools.'' What resources will your students need before they can resolve their conflict? What tools do they have already? What tools can you help them develop? They'll need quadratics, for instance. Help them with that. !!!Act Three ''Resolve the conflict and set up a sequel/extension.'' The third act pays off on the hard work of act two and the motivation of act one. If we've successfully motivated our students in the first act, the payoff in the third act needs to meet their expectations. This should be a climax; a celebration of the accomplishment/solution; fireworks; explosions; whatever. Don't settle for less; don't let the student down with the "usual" encounter of the resolution of their conflict in the back of the textbook. Very important: Make sure you have extension problems ready for students as they finish. !!!Conclusion Many math teachers take act two as their job description. Hit the board, offer students three worked examples and twenty practice problems. As the [[ALEKS|http://www.aleks.com/]] algorithm gets better and Bill Gates throws more gold bricks at Sal Khan (Khan Academy) and more people flip their classrooms, though, it's clear to me that the second act isn't our job anymore. Not the biggest part of it, anyway. You are only one of many people your students can access as they look for resources and tools. Going forward, the value you bring to your math classroom increasingly will be tied up in the first and third acts of mathematical storytelling, your ability to motivate the second act and then pay off on that hard work.
Preparing a lesson plan on Abstraction (one of the [["Big Ideas" in Computer Science|http://www.collegeboard.com/prod_downloads/computerscience/ComputationalThinkingCS_Principles.pdf]]) for a Computer Science class, I came up with a lab/programming exercise that required writing a hierarchy of functions, each one abstracting ("hiding", ignoring) some level of non-essential/low-level details, in order to make the "ultimate level" (the main program) "simple, readable, and elegant".
Defining that "ultimate level" or ultimate function, reminded me of the famous scene from Douglas Adams' "The Hitchhiker's Guide to the Galaxy", where this race of super intelligent (and (of course) hyper dimensional :) beings wants to find the answer to [[the "ultimate question" of Life, The Universe, and Everything|https://en.wikipedia.org/wiki/Phrases_from_The_Hitchhiker%27s_Guide_to_the_Galaxy]].
There is a lot of debate about the answer which the powerful computer [["Deep Thought"|https://en.wikipedia.org/wiki/List_of_minor_The_Hitchhiker%27s_Guide_to_the_Galaxy_characters#Deep_Thought]] gave ([[42|https://en.wikipedia.org/wiki/Phrases_from_The_Hitchhiker's_Guide_to_the_Galaxy#Answer_to_the_Ultimate_Question_of_Life.2C_the_Universe.2C_and_Everything_.2842.29]]), but I have a good, ~CS-related (or at least ~CS-punny) answer to another "immortal question":
>what is the ultimate function (ha!) of living?
The [[Greek-inspired|https://en.wikipedia.org/wiki/Eudaimonia]] answer is a function (of course):
live_a_good_life(each_one_of_us)
The rest, as they say, are details...
As the inimitable [[Terry Pratchett|http://wiki.lspace.org/mediawiki/Biography]] (Sir Terry, mind you :) [[puts it|http://discworld.wikia.com/wiki/The_Fifth_Elephant]], in this conversation between [[Sam Vimes|http://discworld.wikia.com/wiki/Samuel_Vimes]] (a policeman from [[Terry Pratchett]]'s Discworld book series. His full name and title is His Grace, The Duke of Ankh, Commander Sir Samuel Vimes) and [[DEATH|http://www.chrisjoneswriting.com/death.html]] (//Always// "speaking" in Capital Letters): """ GOOD MORNING. Vimes blinked. A tall dark robed figure was now sitting in the boat. 'Are you Death?' IT'S THE SCYTHE, ISN'T IT? PEOPLE ALWAYS NOTICE THE SCYTHE. I’m going to die?’ POSSIBLY. ‘Possibly? You turn up when people are //possibly// going to die?’ OH, YES. IT’S QUITE THE NEW THING. IT’S BECAUSE OF THE UNCERTAINTY PRINICIPLE. 'What’s that?’ I’M NOT SURE. [ha, ha :) ] ‘That’s very helpful.’ I THINK IT MEANS PEOPLE MAY OR MAY NOT DIE. I HAVE TO SAY IT’S PLAYING [[HOB|https://www.merriam-webster.com/dictionary/hob]] WITH MY SCHEDULE, BUT I TRY TO KEEP UP WITH MODERN THOUGHT. """ ---- ^^1^^ - Hob = mischief, trouble, confusion
<<forEachTiddler
where
'tiddler.tags.contains("book-chapter") && tiddler.tags.contains("The Unreasonable Effectiveness of Mathematics")'
sortBy
'tiddler.title'>>
A few influential articles on the subject:
* Richard Hamming on [["The Unreasonable Effectiveness of Mathematics"|http://www.dartmouth.edu/~matc/MathDrama/reading/Hamming.html]]
* Eugene Wigner on The [["Unreasonable Effectiveness of Mathematics in the Natural Sciences"|http://www.dartmouth.edu/~matc/MathDrama/reading/Wigner.html]]
* Frank Wilczek on [["Reasonably effective: I. Deconstructing a miracle"|http://ned.ipac.caltech.edu/level5/March07/Wilczek/Wilczek.html]]
* Mario Livio on [[Is Math a human invention or a series of discoveries of truths in the real world?]]
I am reading Janna Levin's book [[A Madman Dreams of Turing Machines|http://jannalevin.com/black-hole-blues-and-other-songs-from-outer-space/a-madman-dreams-of-turing-machines/]] (about Alan Turing and Kurt Gödel), and came across her reference to Raymond Smullyan's list of [["self-annihilating" sentences|Self-annihilating sentences]]. This (obviously :) intrigued me, and led me to search for Smullyan's book (where the list is) called //5000 B.C. and Other Philosophical Fantasies//. In his book (chapter 3, section 65), Smullyan has a description of a "Gödelian Machine" which turns out to (possibly) be ''The world's shortest explanation of Gödel's theorem''. You can compare the description below to [[Gödel's Second Incompleteness Theorem Explained in Words of One Syllable|resources/Boolos-godel-in-single-syllables.pdf]]. But I found a short (ha!) [[blog by Mark Dominus|https://blog.plover.com/math/Gdl-Smullyan.html]] that slightly (ha, ha!) elaborates on Smullyan, so (from the blog): So here, shamelessly stolen from Smullyan, is the World's shortest explanation of Gödel's theorem. We have some sort of machine that prints out statements in some sort of language. It needn't be a statement-printing machine exactly; it could be some sort of technique for taking statements and deciding if they are true. But let's think of it as a machine that prints out statements. In particular, some of the statements that the machine might (or might not) print look like these: P*x (which means that the machine will print x) NP*x (which means that the machine will never print x) PR*x (which means that the machine will print xx) NPR*x (which means that the machine will never print xx) For example, NPR*FOO means that the machine will never print FOOFOO. NP*FOOFOO means the same thing. So far, so good. Now, let's consider the statement NPR*NPR*. This statement asserts that the machine will never print NPR*NPR*. Either the machine prints NPR*NPR*, or it never prints NPR*NPR*. If the machine prints NPR*NPR*, it has printed a false statement. But if the machine never prints NPR*NPR*, then NPR*NPR* is a true statement that the machine never prints. So either the machine sometimes prints false statements, or there are true statements that it never prints. So any machine that prints only true statements must fail to print some true statements. Or conversely, any machine that prints every possible true statement must print some false statements too. The proof of Gödel's theorem shows that there are statements of pure arithmetic that essentially express NPR*NPR*; the trick is to find some way to express NPR*NPR* as a statement about arithmetic, and most of the technical details (and cleverness!) of Gödel's theorem are concerned with this trick. But once the trick is done, the argument can be applied to any machine or other method for producing statements about arithmetic. The conclusion then translates directly: any machine or method that produces statements about arithmetic either sometimes produces false statements, or else there are true statements about arithmetic that it never produces. Because if it produces something like NPR*NPR* then it is wrong, but if it fails to produce NPR*NPR*, then that is a true statement that it has failed to produce. So any machine or other method that produces only true statements about arithmetic must fail to produce some true statements. Hope this helps! (This explanation appears in Smullyan's book 5000 BC and Other Philosophical Fantasies, chapter 3, section 65, which is where I saw it. He discusses it at considerable length in Chapter 16 of The Lady or the Tiger?, "Machines that Talk About Themselves". It also appears in The Mystery of Scheherezade.)
In his [[presentation "Theory of Fun - 10 years later|http://www.raphkoster.com/gaming/gdco12/Koster_Raph_Theory_Fun_10.pdf]] Raph Koster is talking about his original book //Theory of Fun// and has comments relevant to education/learning. He starts by referring to a (mis)quote of [[Chris Crawford]] about [[fun and learning|The art of computer game design and some implications on learning]]. Some interesting observations Koster makes: * Fun in games arises out of mastery. It arises out of comprehension. It is the act of solving puzzles that makes games fun. Which is something Dan Meyer leverages in his [[Three act math|The Three Acts Of A Mathematical Story]] approach. * Some developmental psychologists and theorists (e.g. [[Roger Caillois|http://en.wikipedia.org/wiki/Man,_Play_and_Games]] made the distinction between the two Latin terms ** Ludus - structured activity and explicit rules, and ** Paidia - unstructured and spontaneous activities *** it's interesting that the Latin definition of ludus is either school or game. In ancient Rome, gladiators like Spartacus were taught to fight by people called lanistae in a ludus and then the game at which they fought was also a ludus. *** Another game designer (and philosopher?), Chris Bateman, is also [[referring to these kinds of distinctions|http://onlyagame.typepad.com/only_a_game/2005/12/the_anarchy_of__1.html]] * But in //Theory of Fun//, Koster says that ludus/paidia is a false dichotomy * We live in a world of systems and choose whether to make a given system a game * Since games implicitly teach systems, we have an art form on our hands that actually changes brains. So we had better use it responsibly. ** This echoes my comment on [[Chris Crawford's observations|The art of computer game design and some implications on learning]] about the "emotional response" of a player playing a game, and the ability to leverage this for learning. *** Crawford brings up an interesting point about the nature of the mental processes and experience of a game player as they play. Crawford describes one "emotional response" of this "subjective flow", namely that some //fantastic// happenings in the game resonate with the player's private/subjective reality/world. But another "emotional response" that can be evoked, especially in the context of an educational game can be curiosity (sometimes incredulity, puzzlement, desire to know, as [[observed by Isaac Asimov|The most exciting phrase to hear in science, the one that heralds new discoveries, is not "Eureka!", but "That's funny...".]]), or sense of accomplishment (sometimes satisfaction, [[joy|Song of Joy]], pleasure). * An interesting distinction between fun and delight: delight is an act of recognition, and it is transitory. * A perfectly valid reason to use games is for __practice__, which can be fun if done right, but often isn't * Games are __"deliberate practice" machines__, a-la Anders Ericsson, who wrote in [[The Making of an Expert|http://www.uvm.edu/~pdodds/files/papers/others/everything/ericsson2007a.pdf]]: ** "Deliberate practice" is practice that focuses on tasks beyond your current level of competence and comfort ** New research shows that outstanding performance is the product of years of deliberate practice and coaching, not of any innate talent or skill. ** Why? Since games are: *** Designed to improve performance *** Repeated a lot *** Providing continuous feedback *** Mentally demanding (focus, concentration) *** Hard *** Require clear goals It's interesting to compare what Todd Blayone has to say about [[Gamification in education]]
There is hopeful symbolism in the fact that flags do not wave in a vacuum. (said after the Apollo 11 landing on the Moon, (and the planting of the American flag?))
In an article in Aeon titled [["There is no difference between computer art and human art"|https://aeon.co/ideas/there-is-no-such-thing-as-computer-art-it-s-all-just-art]] by Oliver Roeder, he covers many examples of music (e.g., Emily Howell, a computer program by [[David Cope|http://artsites.ucsc.edu/faculty/cope/biography.htm]]), painting (e.g., work by [[Manfred Mohr|http://www.emohr.com/ww4_out.html]]), game playing (e.g. ~DeepBlue by IBM, ~AlphaGo by ~DeepMind/Google), and so on, executed ("performed"?) by computers.
Roeder concludes the article:
>But the honest-to-God truth, at the end of all of this, is that this whole notion is in some way a put-on: a distinction without a difference. ‘Computer art’ doesn’t really exist in an any more provocative sense than ‘paint art’ or ‘piano art’ [or 'camera art'] does. The algorithmic software was written by a human, after all, using theories thought up by a human, using a computer built by a human, using specs written by a human, using materials gathered by a human, at a company staffed by humans, using tools built by a human, and so on. Computer art is human art – a subset rather than a distinction. It’s safe to release the tension.
>
>A different human commentator, after witnessing the program beat the human champ at Go, felt physically fine and struck a different note: ‘An amazing result for technology. And a compliment to the incredible capabilities of the human brain.’ So it is with computer art. It’s a compliment to the human brain – and a complement to oil paints and saxophone brass.
Thinking is the negotiation of relationships between our noisy representations (in our heads) and "what's out there". [[Alan Kay|https://en.wikipedia.org/wiki/Alan_Kay]] (a "[[CS Sage|https://en.wikipedia.org/wiki/List_of_computer_scientists]]") at the MIT Media Lab (30 year celebration): The music is not in the pipe organ. and by analogy, The computer is the instrument whose music is ideas! [img[Thinking and computers|resources/ComputerMusic1.png][resources/ComputerMusic.png]] Reflecting the above: There’s a story about Jascha Heifetz, the famously dyspeptic [irritable] Russian violinist and giant of the golden age of recording: After a concert one evening, an admirer went to visit the soloist in his dressing room. “Mr. Heifetz,” he gushed, “what a performance! Your violin has such a gorgeous tone!” Heifetz picked up his instrument, held it to his ear and knit his brow. “I don’t hear anything.”
The new modified tiddlers are tagged with "''hmark modification''" * Created a modified (from the shadow tiddler $:/core/images/quote) regular (non-shadow, non-system) tiddler for transcluding the quote image tiddler: [[imgquote]] ** modified the size from 22px to 12px ** see example of usage at [[Welcome]] * Created a modified (from the shadow tiddler $:/core/images/blank) regular (non-shadow, non-system) tiddler for transcluding the blank image tiddler: [[imgblank]] ** modified the size from 22px to 12px ** see example of usage at [[we are messily slouching...|we are messily slouching towards a non-pastoral utopia on an asymptotic trajectory where reality gradually blurs into magic, waste into wealth, technology into nature and work into play.]] * Created a tiddler titled [[$:/tags/Stylesheet]] and tagged "$:/tags/Stylesheet". and added stylesheet code for borderless HTML tables. ** see example of usage in [[Welcome]].
Those who overrate their own understanding undercut their own potential for learning. from Chris Crawford's book [[The Art of Computer Game Design|resources/computer game design - chris crawford.pdf]]
In [[an excellent article|https://mathbabe.org/2016/06/15/thoughts-on-the-future-of-math-education/]] (a guest post) on the [[mathbabe blog|https://mathbabe.org/]], Kevin H. Wilson (a data scientist) expressed his opinion on Computing (and Math) education. It significantly aligns with my own thoughts/vision on the topic. Here are a few highlights: * __Programming is a Tool and Should be Taught as Such__ ** Wilson claims (and I totally agree) that the current CS initiatives (at a global, American, and state levels) miss the main point of Computing, which is that it can and has affected many and significant aspects of our lives. As such, Computing in the education system should not be constrained to Computer Science class(es) or Programming class(es), but be pervasive, linked with, and linking to other classes and subjects, or even better (but more ambitiously), embedded in other classes and curricula. As he notes, this kind of tight integration of a "literacy" has been done before and with other skills: >To properly teach a tool, it must be used in context and reinforced horizontally (across the school day in multiple subjects) and vertically (across the years as students become more comfortable with more complicated tools). These imperatives have found purchase before, often in the form of encouraging medium- or long-form writing in all subjects, or in the use of (some) math in all science-based courses. ** The danger of keeping things (knowledge, subject domains) compartmentalized (or silo'd) is the unfortunate and damaging misperception among students and in society in general that >knowledge is a bunch of tiny islands whose inhabitants are called the “Good at Math” or the “Good at English.” * __The link between Math and Computing, and the implication to the math curricula:__ > I believe that computers and their ability to easily manipulate data offers a chance to truly redefine the mathematics curriculum, to make it more horizontal, and to refocus the tools we teach on what is actually useful and stimulating. > - Statistics, not calculus, should be the pinnacle achievement of high school, not relegated to box-and-whisker plots and an AP course which is accepted by relatively few universities. > - Algebra, the math of manipulating symbols, should be taught alongside programming. > - Calculus, a course which I have heard multiple people describe as “easy but for the Algebra,” should be relegated to a unit in Statistics. > - Trigonometric identities and conics should go away. > - And earlier math should focus on how and why a student arrives at an answer, and why her procedure always works, not just the answer itself. * __So why is the math curriculum the way it is?__ ** One reason is that ''Historically Computation was Hard''. Wilson correctly points out that many of the important, meaningful, and exciting skills and knowledge in math involved a lot of hard and manual work. Because they were time consuming and hard to perform (let alone repeat multiple times), they were seen as activities and items which would lower the student motivation and understanding (which is probably true :( , and therefore not included in the curriculum. *** But Computing has changed that. Nowadays, very tedious, long, complicated calculations, simulations, and presentations/displays can be done instantly, and therefore, we should revisit old/established curricula decisions, and change things if it makes sense in light of our new Computing capabilities. ** Another reason is that ''we teach what is easy to measure, assess, evaluate, and grade''. Teaching (and grading) the correct execution of math symbol manipulation, computing algorithms, model creation and execution is easy, and in many cases can be (at least somewhat) automated (i.e., multiple choice questions, final answer, end result credit/grade, etc.). *** The hard things to measure/assess/evaluate/grade are the reasons, analysis, justifications, and implications of selecting data, constructing models, reducing biases, verifying conclusions, etc., all of which are part of the process and come before or after the "easier" part of executing and calculating. The hard parts take the form of reasoning, writing, persuading, displaying and communicating, which are harder to measure/grade, and therefore we tend to drop them from the curricula. ** A third reason for the current state of things is that ''//virtually all// learning happens in the classroom, and done mainly by the teacher''. This imposes many limitations on significant and deep learning. *** Computers (calculations, simulations, displays, sensing, monitoring, communicating, networking) can expand and deepen the learning experiences and their relevance/meaning to the learners and society. ** A forth reason is that ''teachers know how to teach the current curricula. Opportunities to experiment/change/expand content and techniques are rare and bureaucraticaly complicated''. *** The teacher evaluation, development, and promotion processes are biased towards "maintaining a solid status quo". And excellent/master teachers get recognized and promoted by becoming part of the administration (and not part of a teacher improvement/development process/program). >>teachers are given very little time to reflect on their teaching, to observe each other, or to, heaven forbid, write about their work in local, regional, or national journals and conferences. It is not at all implausible to imagine a teacher promotion system which includes an academic (as in “the academy”) component. * __ Suggestions for improvement__ Wilson suggests an addition/improvement to the curricula taught at school, in the form of "a project that high school seniors would complete before graduation that would serve as the culmination of their years of study. [..] a project which explicitly uses all the tools students have learned over their years of high school to advocate for change in their communities." >these projects require a broad range of skills which high schoolers should be proficient in. They require long to medium term planning, they require a reasonable amount of statistical knowledge, they require the ability to manipulate data, they require an understanding of historical trends, and they require the ability to write a piece of persuasive writing that distills and interprets large numbers of facts. >Moreover, such projects have the potential to impact their communities in profound ways. >What most interests me, though, is the sort of work that computers and statistics could open up. Imagine a project in which students identified a potential problem in their community, collected and analyzed data about that problem, and then presented that report to someone who could potentially make changes to the community. Perhaps their data could come from public records, or perhaps their data could come from interviews with community members, or from some other physical collection mechanism they devise. >Imagine a world where students build hardware and place it around their community to measure the effects of pollutants or the weather or traffic. Imagine students analyzing which intersections in their town see the most deaths. Imagine students looking at their community’s finances and finding corruption with tools like Benford’s law. >Or for those who do not come up with an original idea, imagine continuing a long running project, like the school newspaper, but instead the school’s annual weather report, analyzing how the data has changed over time. ''The following are Wilson's opinions and recommendations'' * __What Curriculum is Necessary to Support these Projects?__ ** Computing and Algebra curricula should be tightly aligned and collaborating. >[Both programming and algebra are] essentially arithmetic abstracted. Algebra focuses a bit more on the individual puzzle, and programming focuses a bit more on realizing the general answer, but beyond this, they fundamentally amount to the realization that when symbols stand in for data, we may begin to see the forest and not the trees. ** Teaching Discrete Math and Data Structures (instead of Geometry). >[Similarly to geometry courses, in] a course in discrete math and data structures [...] students would still be asked to construct proofs, but the investigation of the facts would involve programming numerous examples and extrapolating the most likely answer from those examples. >Students would come much more prepared to answer questions in discrete math having essentially become familiar with induction and recursion in their programming classes. >Many of these types of empirical studies would also be the beginning of a statistical education. ** Teaching Statistics based on Open Data Sets (instead of Algebra II) > a course on statistics, expanding on the statistical knowledge that our data structures course laid the foundation for. However, since students have experience in programming and data structures, we can go much, much further than what we traditionally expect from a traditional statistics course. We would still teach about means and medians and z-tests and t-tests, but we can also teach about the extraordinarily powerful permutation test. Here students can really come to understand the hard lessons about what exactly is randomness and what is noise and why these tests are necessary. >The focus should move away from memorized rules of thumb for small samples to the actual analysis portion and the implications of their explorations for society. >Projects in this course would be multipage reports about exploring their data sets. They would include executive summaries, charts, historical analysis, and policy recommendations. This is a hugely important form of writing which is often not a part of the high school curriculum at all. ** Teach Machine Learning (Calculus becomes a unit in this course) >[This course would be] an overview of various mathematical and statistical techniques from across the subject, though perhaps the two major themes are linear algebra, especially eigenvectors, and Bayesian statistics, especially the idea of priors, likelihoods, and posteriors. Along the way students would pick up all the Calculus they’ll likely need as they learn about optimizing functions. >the real capstone of this course of study would be the capstone project. The three previous classes contain all that is necessary to be able to approach such a project, though many other classes that students might take could be brought to bear in spectacular ways. History courses could help students put what they learn into the context of the past; biology courses might yield fruitful areas of study, e.g., around pollution; journalism courses might lead to an interest in public records. * __Benefits of this change in curricula__ ** it loosens the tight prerequisite chains in the math curriculum, where "if you don't pass a hurdle, you are doomed". ** it also makes the curricula more relevant to the time (21st Century Learning) and place (community, society) >The focus shifts from performing specific tasks (like manipulating one trigonometric expression into another) to being able to constantly improve a set of skills, specifically, looking out into the world, identifying a problem, collecting data on that problem, and using that data to help determine means to address that problem. >These skills, identifying problems and supporting the analysis of those problems with facts, is a skill whose importance is paramount. Indeed, the Common Core State Standards for English and Language Arts bring up this point as early as the Seventh Grade.[15] But as data become easier to gather and process, “facts” shall come more and more to mean monstrous collections of data. And being able to discern what “facts” are plausible from these collections of data becomes more and more important.
I love Robert Wright's book introductions (see, for example, [[Nonzero: The Logic of Human Destiny]]). This book (see [[The New York Times review|https://www.nytimes.com/1988/08/07/books/wanted-the-meaning-of-life.html]]) starts with his typical understatement and deadpan- (but also dead-serious-) ness: >A NOTE TO READERS > >I don't want to alarm you, but this book is about -- >1. the concept of information; >2. the concepts of meaning and purpose, in both their mundane and cosmic senses; >3. the function of information at various levels of organic organization (in bacteria, ant colonies, human brains, and supermarket chains, for example), with particular emphasis on its role in reconciling life with the second law of thermodynamics; >4. the meaning of the information age, viewed in light of the role information has played throughout evolution; >5. the meaning of life, and >6. a couple of other issues at the intersection of religion and science.[^^1^^] > >Now for the good news: this book is also about three living, breathing, and, I think, unusually interesting human beings. In fact, they are what the book is mainly about. So, for the most part, all you have to do is read about them, about their personal histories, their ways of living, and their very ambitious ways of thinking about the universe and our place in it, and let the above subjects emerge in the process. It will be fairly painless, as these things go. The first part of the book covers Edward Fredkin (of [["The Universe is a Simulation"|http://www.digitalphilosophy.org/index.php/essays/]] fame)^^2^^. Fredkin believes that his way of looking at the world from an "informational viewpoint" addresses the "three great philosophical questions": * what is life? * What is consciousness and thinking and memory and all that? * How does the universe work? As part of his work on Computing, Fredkin came up with a "reversible computer", made of [[reversible "Fredkin (logic) Gates"|On reversible computers and logic]]. ---- ^^1^^ Wright once commented that "Science and religion, like the lion and the lamb, seldom lie down together. But when a scientist stumbles upon a plausible unifying principle behind the world's workings — Darwin upon natural selection, say, or Einstein upon relativity — he transforms himself from searcher into believer." ^^2^^ - [[Langton said|Christopher Langton on Dynamical Patterns]] about Fredkin's ideas: "[Fredkin thinks that] the universe as we know it is an artifact in a computer in a more "real" universe^^3^^. This is a very nice notion, if only for the perspective to be gained from it as a thought experiment — as a way to enhance one's objectivity with respect to the reality one's embedded in." ^^3^^ - Nothing new under the sun? see [[Sallustius]]'s take on [[the nature of reality|One may call the world a myth, in which bodies and things are visible, but souls and minds hidden...]]
Tips & Tricks:
* if you want to create a list of tiddlers which are tagged with a tag which is the title of a tiddler:
** `<<list-links "[tag{!!title}]">>`
* if you want to create a list of tiddlers which are tagged with a tag which is a specific string or category:
** `<<list-links "[tag[Authentic Happiness]]">>`
** or multiple tags AND'ed (no spaces, all in ''one'' enclosing [ ]:
*** and `<<list-links "[tag[Authentic Happiness]!tag[book]]">>`
*** and+not: `<<list-links "[tag[Authentic Happiness]!tag[book]]">>`
** or multiple tags OR'ed (no spaces, each in its ''own'' enclosing [ ]:
*** `<<list-links "[tag[Authentic Happiness]] [tag[book]]">>`
* to insert an image (thumbnail) which when clicked will be bigger:
** `<a href="./resources/some_image.gif" target="new"><img src="./resources/some_image.gif" width="50%" height="50%" /></a>`
Similar to a [[Seagull Moment|Seagull moment]] (and containing one in it!), this is a snippet by Terry Pratchett from his book Thief of Time.
It describes what happens right after Wen ("The Eternally Surprised") had an "extra-ordinary experience" (having to do with the nature of time and our perception of it) during the night.
>“I remember yesterday,” said Wen, thoughtfully. “But the memory is in my head now. Was yesterday real? Or is it only the memory that is real? Truly, yesterday I was not born.”
>Clodpool’s face became a mask of agonized incomprehension.
>“Dear stupid Clodpool, I have learned everything,” said Wen. “In the cup of the hand there is no past, no future. There is only now. There is no time but the present. We have a great deal to do.”
>Clodpool hesitated. There was something new about his master.
>There was a glow in his eyes and, when he moved, there were strange silvery-blue lights in the air, like reflections from liquid mirrors.
>“She has told me everything,” Wen went on. “I know that time was made for men, not the other way around. I have learned how to shape it and bend it. I know how to make a moment last forever, because it already has. And I can teach these skills even to you, Clodpool. I have heard the heartbeat of the universe. I know the answers to many questions. Ask me.”
>The apprentice gave him a bleary look. It was too early in the morning for it to be early in the morning. That was the only thing that he currently knew for sure.
>“Er…what does master want for breakfast?” he said.
>Wen looked down from their camp, and across the snowfields and purple mountains to the golden daylight creating the world, and mused upon certain aspects of humanity.
>“Ah,” he said. “One of the difficult ones.”
To improve is to change; to be perfect is to change often.
A serendipitous path (more like a //web//, actually) that went something like this, led to this writing: about a week ago we were invited to dinner with a lovely family, where I had a short discussion with one of the hosts about visualization for understanding. I had mentioned some of [[Bret Victor's work|http://worrydream.com/]], which I like and [[wrote about|Enabling to think the unthinkable]], and also followed up by emailing links to a couple of his excellent examples on visualizing software code execution, and layers of abstraction. A few days later, I was Googling for technology news/updates on what Victor calls [[reactive documents|http://worrydream.com/ExplorableExplanations/]] and which he implemented in ~JavaScript as [[Tangle|http://worrydream.com/Tangle/]], and one of the results was an [[article by Evan Miller titled Don't Kill Math|http://www.evanmiller.org/dont-kill-math.html]], echoing [[Victor's original article titled Kill Math|http://worrydream.com/KillMath/]]. I'll get to both articles in a moment, but the serendipity continues... Yesterday, I picked up a book by Ivars Peterson (author of //The Mathematics Tourist//) titled //Islands of Truth (A mathematical mystery cruise)// in which he mentions in the 2^^nd^^ page of the preface "physicist David Gross's witty look at the relationship between physics and mathematics". So obviously, I had to find [[Gorss's article (titled Physics and mathematics at the frontier)|resources/Gross-Physics and Mathematics at the Frontier.pdf]]. Gross's article is very interesting, and one of the topics he discusses is "the Unreasonable Effectiveness of Mathematics in Physics" as written by Eugene Wigner. (I actually got introduced to the topic of ''"why Math works for us?"'' and [[wrote about it|On why Math works for us]] after reading Richard Hamming's [[article|http://www.dartmouth.edu/~matc/MathDrama/reading/Hamming.html]], and Frank Wilczek's [[article|http://www.employees.org/~hmark/resources/Wilczek_reasonably1.pdf]]). I hope I'm not losing you; I'm almost done "unrolling" the serendipity web... Towards the end of Gross's article, he states: >Mathematicians also think differently and have different habits of work than physicists, even when they are exploring similar structures. Mathematicians love to generalize, to extend their concepts to the most general possible case, to construct the most inclusive possible theory. Physicists are of course interested not in the most general case but in the special case of the real world. They also work by simplification, idealization, and by the construction of specific examples. We might say that mathematicians labor to construct interesting and useful definitions from which good theorems flow, physicists to construct interesting and useful models from which good predictions flow. And the differences between mathematicians and physicists in terms of their ways of thinking, their goals, and their methods, are I believe at the crux of the disagreement between Victor and Miller as to whether to "kill math" or not. I had read Victor's Kill Math article months ago, and did not remember all the details, but when reading Miller's reaction, I thought I should read it again, since it seems like Miller is saying that Victor has "dismissive attitudes toward analytic methods in the sciences", and is claiming that: > interactive interfaces [Haggai: simulations, models] can and should replace traditional analytic methods for practicing scientists and engineers because interactive interfaces convey deeper understanding than their analytic counterparts. Miller has some very valid points and strong arguments, but, I think that this is another case of "the power of 'The And'", where the real power and advantage is in using ''both'' Math/analytics ''and'' Physics/simulation. [[George Polya|http://en.wikipedia.org/wiki/George_P%C3%B3lya]] (of [["How to Solve it"|https://notendur.hi.is/hei2/teaching/Polya_HowToSolveIt.pdf]] fame), has a lot to say about intuition, conjectures, guessing, and plausible reasoning, in the introduction to his book [[Induction And Analogy In Mathematics|https://archive.org/download/Induction_And_Analogy_In_Mathematics_1_/Induction_And_Analogy_In_Mathematics_1_.pdf]]: >Strictly speaking, all our knowledge outside mathematics and demonstrative logic (which is, in fact, a branch of mathematics) consists of conjectures. >[...]We secure our mathematical knowledge by demonstrative reasoning, but we support our conjectures by plausible reasoning, A mathematical proof is demonstrative reasoning, but the inductive evidence of the physicist, the circumstantial evidence of the lawyer, the documentary evidence of the historian, and the statistical evidence of the economist belong to plausible reasoning. I believe that this ability to "bounce" between analytic methods and simulations and modeling is a "constructive ladder" (different from the ladder of abstraction, but achieving similar goals in terms of knowledge and insights), where intuitions and formal analytics build on each other very effectively (and herein lays the "miracle" of "how math works so well for us"). Or in Polya's words: >Finished mathematics presented in a finished form appears as purely demonstrative, consisting of proofs only. Yet mathematics in the making resembles any other human knowledge in the making. You have to guess a mathematical theorem before you prove it; you have to guess the idea of the proof before you carry through the details. You have to combine observations and follow analogies; you have to try and try again. The result of the mathematician's creative work is demonstrative reasoning, a proof; but the proof is discovered by plausible reasoning, by guessing. When Victor writes that >When most people speak of Math, what they have in mind is more its mechanism than its essence. This "Math" consists of assigning meaning to a set of symbols, blindly shuffling around these symbols according to arcane rules, and then interpreting a meaning from the shuffled result. >... The symbolic shuffle should no longer be taken for granted as the fundamental mechanism for understanding quantity and change. Math needs a new interface. I believe he is criticizing what Polya calls "demonstrative reasoning", and claims that the "symbol manipulations" in Math are ''an interface'' (and he suggests a different User Interface (UI)). And that's where I disagree with Victor, since I strongly believe (and agree with Miller on this point) that there is knowledge to be gained by manipulating (Victor's "shuffling") and analyzing the symbols and relationships for meaning. In this sense this activity is definitely not "just a user interface", which Victor is explaining as the natural growth of pencil and paper technologies we had in the past. If anything, I would draw similarities between analytics/shuffling and the goal-driven activity of a person manipulating a software user interface (a-la Victor's suggestion), including visual zooming, rotating, transforming, etc. Both modes and procedures yield knowledge/insights, and as such should be learned and exercised as appropriate. Victor may be focusing on the trees (the formal/demonstrative actions, or the equivalent manipulations of a User Interface) and missing the forest (the knowledge/insights gained from the results/manipulations). !!!!A simple example of analytic manipulation and simulation/visualization complimenting each other A while ago I had taught a Citizen Schools [[course called Right on Target|The "Right on Target" course]]. Since it was targeted at middle school students, the main concepts of [[ballistic trajectories|http://en.wikipedia.org/wiki/Ballistic_trajectory]] were explored through simulation and game playing (e.g., hitting targets with missiles). Knowing the math (or looking it up on [[Wikipedia||http://en.wikipedia.org/wiki/Ballistic_trajectory]]): To hit a target at range x and altitude y when fired from (0,0) and with initial speed v the required angle(s) of launch theta are: [img[ballistic trajectory - angle|resources/ballistic-trajectory-formula.png][resources/ballistic-trajectory-formula.png]] The +/- in the equation means that there are 2 solutions/angles which will lead to hitting the target at (x,y), given velocity v. The simulation can show that this is really true, and if the UI enables setting the parameters and/or a sweep of all angles, then we can see it happen. ''But'', even if the UI enables the visualization of the 2 possible solutions, the question or risk is that users will not see/explore/find them (and this is actually what happened to some students in my class). ''Moreover'', from the visualization/simulation/UI it may not be clear whether there are more than 2 solutions/angles, whereas, from the math/equation, a trained person (and this was one of Victor's points, namely, you have to be "in the know"), can indeed see that there are only 2 (real!) solutions. So, this is a simple case where knowing the math __can guide your activity__ within a simulation. On the flip side, playing with the simulation gives you a strong sense of what's possible, making it intuitive that there are no more than 2 solutions. But, to Polya's point, the formalism of the math is the proof. [img[ballistic trajectory - simulation|resources/ejs-balistic-trajectory-1.png][resources/ejs-balistic-trajectory-1.png]] [[A simulation|http://www.employees.org/~hmark/math/ejs/RightOnTarget.html]] showing a target at x=30, y=20, and a projectile with v=30. The two hitting angles are 45 and 79 degrees.
To teach is to learn twice.
!!!! Tiddler creation/updates * Look up Hofstadter's criticism of Searle talking about "intelligent beer cans" to ridicule the idea that "intelligent behavior" can be an emergent phenomenon originating from very basic operations/activities. ** link this to Dennett's coverage of top-down deconstruction to demonstrate "intelligent behavior" ** link this to Melanie Mitchell's tiddler on [[CA and computing|Everything is computation]] ** also, similar to Hofstadter's description of a chain of dominoes set up to calculate/determine the primeness of a number * Analyze and generalize the "ladder of abstraction" with [[this beautiful example|http://worrydream.com/LadderOfAbstraction/]] by Bret Victor (with the text only [ext[here|resources/Up and Down the Ladder of Abstraction.htm]]) * Analyze [[Simulation as a Practical Tool|http://worrydream.com/SimulationAsAPracticalTool/]] by Bret Victor (October 19, 2009) (with the text only [[here|resources/Simulation as a Practical Tool.htm]]), to see if it ties to my idea of the [[Universal Emulator|Universal Emulator]] * Extract useful principles for and draw parallels to the [[Universal Emulator|Universal Emulator]] from Feynman's article on [ext[simulating Physics with computers|resources/Feynman_simulating_physics.pdf]] * Analyze the atheistic point of view of Fredkin about the soul as [ext[an informational construct|resources/Fredkin - on the soul.pdf]] * Summarize Anders Ericsson's article in the Harvard Business Review [ext[The Making of an Expert|resources/Ericsson - making of an expert.pdf]] * Summarize Anders Ericsson's article in Psychological Review [ext[The Role of Deliberate Practice in the Acquisition of Expert Performance|resources/Ericsson - DeliberatePractice.pdf]] !!!! Permalinks * https://tinyurl.com/haggai-ed-wiki - "Education" and "Computational Thinking" lists of topics * ''~TidlyWiki at Stanford LDT: https://tinyurl.com/hmark-wiki'' * search engine by keyword: haggaimarkwiki or ~HaggaiMarkWiki * Welcome and Education TOC tiddler: http://tinyurl.com/HaggaiLDT1 * Education TOC tiddler with Citizen Schools examples: http://tinyurl.com/HaggaiLDT * Computational Thinking, Computational Literacy in the classroom - examples: http://tinyurl.com/HaggaiCT2 * A Framework for Computational Thinking, Computational Literacy: http://tinyurl.com/HaggaiCT1 * Re-taught Amazing Mazes course at Citizen Schools with teacher wikispaces site and lesson plans: http://tinyurl.com/HaggaiMazes2 * Original Amazing Mazes course at Citizen Schools: http://tinyurl.com/HaggaiMazes * Amazing Mazes course - 2 blog entries for 2 offerings - http://tinyurl.com/HaggaiAmazingMazes2 * Computational Literacy/Thinking in Physical and Earth Sciences: http://tinyurl.com/HaggaiLabReady1 * Teaching Sparks, Learning Moments - http://tinyurl.com/HaggaiSparks * About Me page and Education TOC - http://tinyurl.com/HaggaiFinStateEd * Formalism and Intuition - Rigor Mortise - http://tinyurl.com/HaggaiRigorMortise
As part of teaching the [[Right on Target course|The "Right on Target" course]] at Citizen Schools, we watched and discussed [[a video of a simple experiment|resources/GalileoFallingBodiesGravityDemo.mp4]] showing how two falling bodies with different masses behave when pulled by gravity, and when air resistance is negligible.
It's __qualitatively__ obvious (click on the image below to see the video) what happens to the two objects, but the ~OpenSource [[video analysis tool "Tracker"|http://www.compadre.org/osp/items/detail.cfm?ID=9687]] can be used to __quantitatively__ analyze the behavior of these bodies in free-fall. In this experiment, a tennis ball and a bowling ball are dropped from the top of a school gym structure, and Tracker is used to analyze the fall.
[img[Freefalling bodies|resources/TowerOfPisa_at school2.png][resources/GalileoFallingBodiesGravityDemo.mp4]]
Tracker is fairly easy to use:
* It involves importing the video
** it should be good quality (it works with (.mov, .avi, .mp4, .flv, .wmv, etc.)
** it should be shot from a single, static (ideally, front-view) position/camera
* setting the coordinate system (x-y, origin) - see the pink/purple lines
* setting the scale - see the blue double arrow
* clicking through the video, one (or more) frame(s) at a time, and marking the objects (in this case one of the falling balls) you want to track - see the red diamonds
As you mark the tracked objects, Tracker displays __multiple representations__ of the motion, in the form of a graph, a table, and the markers on the video clip. It is easy to add or toggle between the various variables you want to display (e.g. time (t), vertical distance (y), vertical speed (V~~y~~), vertical acceleration (a~~y~~), etc.), which Tracker can automatically calculate for you.
This tool and technique provides an easy and powerful way to "quantify what you see". It can be used to 'verify the theory', or to help create a model. The pedagogical approach of using the analysis tool to explore and 'invent' a model, //before// the theory is taught/told, can be very effective in getting learners "hooked" (since they came up with an explanation/theory, and are now "committed"), and in getting them to build theoretical, "deep structures" for themselves, which can be built upon by the teach/tell that follows. [[Daniel Schwartz and his students at Stanford showed in experiments|http://aaalab.stanford.edu/papers/DBChin_PracticingvsInventing_JEP5_FINAL_20110720.pdf]] that this approach (where learners actively explore and invent mental models, //before// being taught/told the material/theory/concepts) leads to better mental models ("deep structures") and higher transfer of learning to new/novel situations, which is a very desirable learning outcome, especially in STEM (Science, Technology, Engineering, Math) education.
From Chris Crawford's book [[The Art of Computer Game Design|resources/computer game design - chris crawford.pdf]]: >PRECEPT #2: DON'T TRANSPLANT >One of the most disgusting denizens of computer gamedom is the transplanted game. This is a game design originally developed on another medium that some misguided soul has seen fit to reincarnate on a computer. The high incidence of this practice does not excuse its fundamental folly. The most generous reaction I can muster is the observation that we are in the early stages of computer game design; we have no sure guidelines and must rely on existing technologies to guide us. Some day we will look back on these early transplanted games with the same derision with which we look on early aircraft designs based on flapping wings. >Why do I so vehemently denounce transplanted games? Because they are design bastards, the illegitimate children of two technologies that have nothing in common. Consider the worst example I have discovered so far, a computer craps game. The computer displays and rolls two dice for the player in a standard game of craps. The computer plays the game perfectly well, but that is not the point. The point is, why bother implementing on the computer a game that works perfectly well on another technology? A pair of dice can be had for less than a dollar. Indeed, a strong case can be made that the computer version is less successful than the original. Apparently one of the appeals of the game of craps is the right of the player to shake the dice himself. Many players share the belief that proper grip on the dice, or speaking to them, or perhaps kissing them will improve their luck. Thus, the player can maintain the illusion of control, of participation rather than observation. >The computer provides none of this; the mathematics may be the same, but the fantasy and illusion aren t there. Seymour Papert has identified the principle of [[New media should equal New Content|An Exploration in the Space of Mathematics Educations]] as a sound design principle or practice for learning/education. On [[other implications of game design for learning|The art of computer game design and some implications on learning]]
Inspired by [[David Whyte|David Whyte - questions]], I almost decided to write 'pilgrim' (defined: a person who journeys, especially a long distance, to some sacred place as an act of __religious__ devotion), but opted for 'traveler', which has less religious connotations. I wish there was a better word, associated with ''spirituality'' (which is at the heart of what I have in mind here) but not necessarily with ''religion''. [[Douglas Adams captured|It [evolution] was a concept of such stunning simplicity, but it gave rise, naturally, to all of the infinite and baffling complexity of life. The awe it inspired in me made the awe that people talk about in respect of religious experience seem, frankly, silly beside it. I'd take the awe of understanding over the awe of ignorance any day.]] the two very different senses of spirituality well.
After reading a [[hilarious short article by Umberto Eco|http://www.thephora.net/forum/archive/index.php/t-77477.html]] (the author of the excellent novel "The Name of the Rose", which has been described as "an intellectual mystery combining semiotics in fiction, biblical analysis, medieval studies and literary theory"), and enjoying his conversational, intelligent, and thoughtful academic style (which has been described as "reading 'like a novel', opinionated, frequently irreverent, sometimes polemical, and often hilarious"), I was also (pleasantly) surprised by his unusual use of parentheses -- similar to my own writing style (Delightful! (if I say so myself :))
So I searched for comments on Eco's [[writing style|Why writing style matters]] and came up with his [[enjoyable set of rules for writing|http://gioclairval.blogspot.com/2010/02/umberto-ecos-rules-for-writing-well.html]]. (See also [[99 writing styles by Raymond Queneau|Exercises in Style - Raymond Queneau]])
''Reading instructions'': When done reading the list below (or at some point in the middle), don't forget to read the reading instructions at the bottom of these writing rules!
So here's Eco's advice:
1. Avoid alliterations, even if they're manna for morons.
2. Don't contribute to the killing of the subjunctive mode, I suggest that the writer use it when necessary.
3. Avoid clichés: they're like death warmed over.
4. Thou shall express thyself in the simplest of fashions.
5. Don't use acronyms & abbreviations, etc.
6. (Always) remember that parentheses (even when they seem indispensable) interrupt the flow.
7. Beware of indigestion... of ellipses.
8. Limit the use of inverted commas. Quotes aren't "elegant."
9. Never generalize.
10. Foreign words aren't bon ton.
11. Hold those quotes. Emerson aptly said, "I hate quotes. Tell me only what you know."
12. Similes are like catch phrases.
13. Don't be repetitious; don't repeat the same thing twice; repeating is superfluous (redundancy means the useless explanation of something the reader has already understood).
14. Only twats use swear words.
15. Always be somehow specific.
16. Hyperbole is the most extraordinary of expressive techniques.
17. Don't write one-word sentences. Ever.
18. Beware too-daring metaphors: they are feathers on a serpent's scales.
19. Put, commas, in the appropriate places.
20. Recognize the difference between the semicolon and the colon: even if it's hard.
21. If you can't find the appropriate expression, refrain from using colloquial/dialectal expressions. In Venice, they say "Peso el tacòn del buso". "The patch is worse than the hole".
22. Do you really need rhetorical questions?
23. Be concise; try expressing your thoughts with the least possible number of words, avoiding long sentences-- or sentences interrupted by incidental phrases that always confuse the casual reader-- in order to avoid contributing to the general pollution of information, which is surely (particularly when it is uselessly ripe with unnecessary explanations, or at least non indispensable specifications) one of the tragedies of our media-dominated time.
24. Don't be emphatic! Be careful with exclamation marks!
25. Spell foreign names correctly, like Beaudelaire, Roosewelt, Niezsche and so on.
26. Name the authors and characters you refer to, without using periphrases. So did the greatest Lombard author of the nineteenth century, the author of "The 5th of May."
27. Begin your text with a captatio benevolentiae, to ingratiate yourself with your reader (but perhaps you're so stupid you don't even know what I'm talking about).
28. Be fastidios with you're speling.
29. No need to tell you how cloying preteritions are [telling by saying you are not going to tell].
30. Do not change paragraph when unneeded.
Not too often.
Anyway.
31. No plurale majestatis, please. We believe it pompous.
32. Do not take the cause for the effect: you would be wrong and thus you would make a mistake.
33. Do not write sentences in which the conclusion doesn't follow the premises in a logical way: if everyone did this, premises would stem from conclusions.
34. Do not indulge in archaic forms, apax legomena and other unused lexemes, nor in deep rizomatic structures which, however appealing to you as epiphanies of the grammatological differance (sic), inviting to a deconstructive tangent – but, even worse it would be if they appeared to be debatable under the scrutiny of anyone who would read them with ecdotic acridity – would go beyond the recipient's cognitive competencies.
35. You should never be wordy. On the other hand, you should not say less than.
36. A complete sentence should comprise.
Befitting Eco's style/spirit and the nature of the above rules, here are the (actually useful) ''reading instructions'' (at their appropriate place :)
Eco had ([[he died in February 2016|http://www.theatlantic.com/entertainment/archive/2016/02/umberto-eco-dies/470235/]]) a great, dry sense of humor, at times very subtle (and at other times not subtle at all). It may not be obvious when reading the first few rules above, but it will dawn on you further down the list, and at some point it'll be very obvious. At that point, it may be a good idea to circle back and read the list from the top, again!
Guaranteed, you have missed some of his points the first time. (Also guaranteed: you'll enjoy it the second time around, too).
Understanding — like civilization, happiness, music, science and a host of other great endeavors — is not a state of being, but a manner of traveling. And the main goal of helping children learn is to find ways to show them that great road which has no final destination, and that manner of traveling in which the journey itself is the reward. :: -- Alan Kay in [[Powerful Ideas Need Love Too|http://worrydream.com/refs/Kay%20-%20Powerful%20Ideas%20Need%20Love%20Too.html]]
From The Free Dictionary: ''em·u·late'' 1. To strive to equal or excel, especially through imitation: an older pupil whose accomplishments and style I emulated. 2. To compete with successfully; approach or attain equality with. 3. //Computer Science// To imitate the function of (another system), as by modifications to hardware or software that allow the imitating system to accept the same data, execute the same programs, and achieve the same results as the imitated system. !!!!Points: * Inspired by Andrea diSessa's ideas about [[computing literacy|Computing Literacy]] and the impact of computing on new ways to learn, teach, and do/perform ** His book "Changing Minds: Computers, Learning, and Literacy" * A learning and [[Performance Support|Human Performance Support]] environment incorporating principles of diSessas's [[Open Toolsets|resources/diSessa- open toolsets.pdf]] ** inspiration from the [[eclipse platform|http://www.eclipse.org/projects/project.php?id=eclipse]], the ideas of plug-ins and components, the drag-and-drop UI, visual editors, domain modelers ** [[difficulties and pitfalls|resources/Spalter_2002a - reusable educational components.pdf]] related to developing and deploying educational components * An environment supporting ** Math computation, visualization ** Physics computation, simulations * Integrating multiple tools and capabilities from different sources ** inspired by [[Sage|http://sagemath.org/]] and its [[integrative design|http://sagemath.org/links-components.html]], all wrapped into a programmable environment
[[UKL's website|http://www.ursulakleguin.com/UKL_info.html]]
<<list-links "[tag{!!title}]">>
Or more specifically of "~Do-It-Yourself Cosmology". From her book //The language of the night -- essays on fantasy and science fiction//: >It would seem that the writer who composes a universe, invents a planet, or even populates a drawing room, is playing God. The creation of people, of worlds, of galaxies-since it all comes out of one's head, surely it must also go to one's head? > >Some years ago, in the Bulletin of the Science Fiction Writers Association, [the ~Sci-Fi writer] [[Poul Anderson|https://en.wikipedia.org/wiki/Poul_Anderson]] published an article called (if I remember rightly), "How to Create a World." Taking it for granted that any reader of that publication would understand the pleasures of autocosmology, he warned gently of the dangers of carelessness, and then got down to the groundwork. Which kind of star is likely to have planets? What size and kind of planet is likely to have life aboard it? At what distance from what size sun? Is the moon's role functional or decorative? And so on, and on. > >People ignorant of science or science fiction are usually convinced that "sci fi writers just make all that up," but of course any halfway serious science fiction writer has to have studied such topics, and to keep reference books handy. Imagination is the essence; but it is controlled, exactly as the profuse strains of unpremeditated Art are controlled by the requirements of fixed or free rhythm and rhyme. As soon as you, the writer, have said, "The green sun had already set, but the red one was hanging like a bloated salami above the mountains,"you had better have a pretty fair idea in your head concerning the type and size of green suns and red suns-especially green ones, which are not the commonest sort-and the arguments concerning the existence of planets in a binary system, and the probable effects of a double primary on orbit, tides, seasons, and biological rhythms; and then of course the mass of your planet and the nature of its atmosphere will tell you a good deal about the height and shape of those mountains; and so on, and on. You may even feel impelled to make a cursory study of the effect of senility upon salamis. None of this background work may actually get into the story. But if you are ignorant of these multiple implications of your pretty red and green suns, you'll make ugly errors, which every fourteen-year-old reading your story will wince at; and if you're bored by the labor of figuring them out, then surely you shouldn't be writing science fiction. A great part of the pleasure of the genre, for both writer and reader, lies in the solidity and precision, the logical elegance, of fantasy stimulated by and extrapolated from scientific fact. > >Wasting no time on apologies, Mr. Anderson provided a good batch of the sort of facts the universe-maker wants, including several mathematical equations useful in various situations. His essay was exemplary. It has received grateful response ever since except for one letter in the next issue, which went like this: > >Dear Mr. Anderson: That is not the way I do it. >Yours truly, GOD > >Undeterred, Mr. Anderson has gone on to enlarge and reprint his useful article. On this particular subject, science fiction writers can only ignore the opinion of God. They have to do it their own way. > >Some quite practical values of their method are beginning to be appreciated. The Russians have used science fiction in the classroom for many years, and there are now American textbooks in sociology, political science, anthropology and psychology presenting science fiction stories as problems or statements of ideas; but, more specifically, a course was offered at an Oregon university last year, taught by a physicist with assistance from astronomers, geologists, etc., which the catalogue cautiously called Planetology, but which the joyful students more accurately called Planet Building. It was highly successful. The more one thinks about it the more one sees the usefulness of Do-It-Yourself cosmology as a device for teaching the general principles, mechanics, and history of the cosmos, the solar system, and the planet Earth. > >A notable feature of this type of world-making -- the sober science-fictional and the classroom-heuristical -- is its modesty. God, as you can see by his letter, is not offended by it; no thunderbolt is called for; he merely points out that it's not the way he goes about the job. He's perfectly aware that these writers and students are not pretending to be, or trying to be, or mistaking themselves for, himself. If they were, he would warn them against what the Greeks called hubris and the Christians pride and the Jungians inflation. But that arrogant identification of the Ego with the Creator Spirit is quite absent here. This kind of world-making is a thought-experiment, performed with the caution and in the controlled, receptive spirit of experiment. Scientist and sciencefictioneer invent worlds in order to reflect and so to clarify, perhaps to glorify, the "real world," the objective Creation. The more closely their work resembles and so illuminates the solidity, complexity, amazingness, and coherence of the original, the happier they are.
In a blog entry on her site titled [[A Message About Messages|http://www.ursulakleguin.com/MessageAboutMessages.html]] ^^1^^ UKL brings up (in her typical strong, clear, and somewhat humorous style) a few good points on the question of are stories vehicles for delivering messages. She writes: >Readers — kids and adults — ask me about the message of one story or another. I want to say to them, “Your question isn’t in the right language.” >As a fiction writer, I don’t speak message. I speak story. Sure, my story means something, but if you want to know what it means, you have to ask the question in terms appropriate to storytelling. Terms such as message are appropriate to expository writing, didactic writing, and sermons — different languages from fiction. And makes the good point: > [if a story] can be reduced to a few abstract words, neatly summarized in a school or college examination paper or a brisk critical review [then] why would writers go to the trouble of making up characters and relationships and plots and scenery and all that? Why not just deliver the message? Is the story a box to hide an idea in, a fancy dress to make a naked idea look pretty, a candy coating to make a bitter idea easier to swallow? She notes that her objection to the question about the message of the story doesn't imply that stories have no meaning. >I believe storytelling is one of the most useful tools we have for achieving meaning: it serves to keep our communities together by asking and saying who we are, and it’s one of the best tools an individual has to find out who I am, what life may ask of me and how I can respond. >But that’s not the same as having a message. The complex meanings of a serious story or novel can be understood only by participation in the language of the story itself. To translate them into a message or reduce them to a sermon distorts, betrays, and destroys them. Stories are an art form, like painting and music. >we know there’s no way to say all a song may mean to us, because the meaning is not so much rational as deeply felt, felt by our emotions and our whole body, and the language of the intellect can’t fully express those understandings. > >In fact, art itself is our language for expressing the understandings of the heart, the body, and the spirit. > >Any reduction of that language into intellectual messages is radically, destructively incomplete. > >This is as true of literature as it is of dance or music or painting. __But because fiction is an art made of words, we tend to think it can be translated into other words without losing anything. So people think a story is just a way of delivering a message.__ (my emphasis.) And she concludes: >Art frees us; and the art of words can take us beyond anything we can say in words. > >[...] I wish, instead of looking for a message when we read a story, we could think, “Here’s a door opening on a new world: what will I find there?” ---- ^^1^^ see also [[Ursula K. Le Guin on Science Fiction, Writing, and the Truth]]
In the [[introduction to her book|http://theliterarylink.com/leguinintro.html]] //The Left Hand of Darkness//^^1^^, Ursula K. Le Guin writes a very insightful and personal description of what writing science fiction means to her ^^2^^.
Here are a few quotes from the introduction:
* She is claiming that ~Sci-Fi is not predictive but rather descriptive:
> - ''Science fiction'' is often described, and even defined, as extrapolative. the science fiction writer is supposed to take a trend or phenomenon of the here-and-now, purify and intensify it for dramatic effect, and extend it into the future. "If this goes on, this is what will happen." A prediction is made.
> - ''Predictions'' are uttered by prophets (free of charge); by clairvoyants (who usually charge a fee, and are therefore more honored in their day than prophets); and by futurologists (salaried). Prediction is the business of prophets, clairvoyants, and futurologists. It is not the business of novelists. A novelist's business is lying.
* About fiction writing and Truth:
> - ''Fiction writers'', at least in their braver moments, do desire the truth: to know it, speak it, serve it. But they go about it in a peculiar and devious way, which consists in inventing persons, places, and events which never did and never will exist or occur, and telling about these fictions in detail and at length and with a great deal of emotion, and then when they are done writing down this pack of lies, they say, There! That's the truth!
> - ''I do not say'' that artists cannot be seers, inspired: that the awen cannot come upon them, and the god speak through them. Who would be an artist if they did not believe that that happens? if they did not know it happens, because they have felt the god within them use their tongue, their hands? Maybe only once, once in their lives. But once is enough.
> - ''I talk about the gods'', I am an atheist. But I am an artist too, and therefore a liar. Distrust everything I say. I am telling the truth. The only truth I can understand or express is, logically defined, a lie. Psychologically defined, a symbol. Aesthetically defined, a metaphor.
> - ''I'm merely observing'', in the peculiar, devious, and thought-experimental manner proper to science fiction, that if you look at us at certain odd times of day in certain weathers, we already are [behaving in a certain way]. I am not predicting, or prescribing. I am describing. I am describing certain aspects of psychological reality in the novelist's way, which is by inventing elaborately circumstantial lies.
* and about readers of fiction:
> - ''They [fiction writers]'' may use all kinds of facts to support their tissue of lies. They may describe the Marshalsea Prison^^3^^, which was a real place, or the battle of Borodino^^4^^, which really was fought, or the process of cloning, which really takes place in laboratories, or the deterioration of a personality, which is described in real textbooks of psychology; and so on. This weight of verifiable place-event-phenomenon-behavior makes the reader forget that he is reading a pure invention, a history that never took place anywhere but in that ulocalisable region, the author's mind. In fact, while we read a novel, we are insane - bonkers. We believe in the existence of people who aren't there, we hear their voices, we watch the battle of Borodino with them, we may even become Napoleon. Sanity returns (in most cases) when the book is closed.
> - ''In reading a novel'', any novel, we have to know perfectly well that the whole thing is nonsense, and then, while reading, believe every word of it. Finally, when we're done with it, we may find - if it's a good novel - that we're a bit different from what we were before we read it, that we have been changed a little, as if by having met a new face, crossed a street we never crossed before. But it's very hard to say just what we learned, how we were changed.
* And about (Science)-Fiction:
> - ''All fiction is metaphor''. Science fiction is metaphor. What sets it apart from older forms of fiction seems to be its use of new metaphors, drawn from certain great dominants of our contemporary life - science, all the sciences, and technology, and the relativistic and the historical outlook, among them. Space travel is one of these metaphors; so is an alternative society, an alternative biology; the future is another. The future, in fiction, is a metaphor.
>A metaphor for what?
>If I could have said it non-metaphorically, I would not have written all these words, this novel (//The Left Hand of Darkness//^^1^^).
* See what Le Guin has to say about [[Patriotism|On Patriotism - Ursula K. Le Guin]]
----
^^1^^ - This ominously-sounding title of the book turns out to be something (surprisingly?) Tao-inspired! Three quarters into the book one of the main characters on the Alien Planet named Winter (an apt name for that "heavenly body" :) quotes a poem ("Tormer's Lay") from a "local" (alien) poet:
> //Light is the left hand of darkness//
> //and darkness the right hand of light.//
> //Two are one, life and death, lying//
> //together like lovers in kemmer//^^5^^,
> //like hands joined together,//
> //like the end and the way.//
^^2^^ - see also [[Ursula K. Le Guin on Literary Messages]]
^^3^^ - a notorious prison in London (closed in 1842); written about by Charles Dickens.
^^4^^ - a major engagement (fought in 1812) in the Napoleonic Wars during the French invasion of Russia.
^^5^^ - the alien word for sexual heat.
""" Island where all becomes clear. Solid ground beneath your feet. The only roads are those that offer access. Bushes bend beneath the weight of proofs. The Tree of Valid Supposition grows here with branches disentangled since time immemorial. The Tree of Understanding, dazzlingly straight and simple, sprouts by the spring called Now I Get It. The thicker the woods, the vaster the vista: the Valley of Obviously. If any doubts arise, the wind dispels them instantly. Echoes stir unsummoned and eagerly explain all the secrets of the worlds. On the right a cave where Meaning lies. On the left the Lake of Deep Conviction. Truth breaks from the bottom and bobs to the surface. Unshakable Confidence towers over the valley. Its peak offers an excellent view of the Essence of Things. For all its charms, the island is uninhabited, and the faint footprints scattered on its beaches turn without exception to the sea. As if all you can do here is leave and plunge, never to return, into the depths. Into unfathomable life. """
In 1982, Mitchell Feigenbaum conducted a charming interview with two Math Greats, Mark Kac and Stan Ulam, where he asked them (among many interesting questions) how they "perceive" physics terms and concepts when doing the related math (since both of them practiced their belief that there should not be a sharp distinction/separation between physics and math). Kac shared his insight into how math is usually done: >I think there are two acts in mathematics. There is the ability to prove and the ability to understand. Now the actions of understanding and of proving are not identical. In fact, it is quite often that you understand something without being able to prove it. >Now, of course, the height of happiness is that you understand it and you can prove it. The next stage is that you don't understand it, but you can prove it. That happens over and over again, and mathematics journals are full of such stuff. Then there is the opposite, that is, where you understand it, but you can't prove it. Fortunately, it then may get into a physics journal. >Finally comes the ultimate of dismalness, which is in fact the usual situation, when you neither understand it nor can you prove it. The way mathematics is taught now and the way it is practiced emphasize the logical and the formal rather than the intuitive, which goes with understanding. >Now I think you would agree with me because, especially with things like geometry, of which Stan's a past master, seeing things-not always leading neatly to a proof, but certainly leading to the understanding-ultimately results in the correct conjecture. And then, of course, the ultimate has to be done also-because of union regulations, you also have to prove it. And Ulam added: >Let me tell you something. It so happens that I have written an article for a jubilee volume in honor of this gentleman here, Mark Kac, on his whatever anniversary, a volume which has not yet appeared. But the article is about analogy and the ways of thinking and reasoning in mathematics and in some other sciences. >So it is sort of an attempt to throw a little light on what he was just talking about. These things are intertwined in a mysterious way, and one of the great hopes, to my mind, of progress, even in mathematics itself, will be more formalizing or at least understanding of the processes that lead both to intuition and to then working out not only the details but also the correct formulations of things. >So there is a very, very deep problem and not enough thought has been really given to it, just cursory remarks made. Feigenbaum asked the Two Sages what their thoughts were on using computers for doing math work, and Kac responded: >Well, actually, computers are a marvelous tool, and there is no reason to fear them. You might say that initially a mathematician should be afraid of pencil and paper because it is sort of a vulgar tool compared with pure thought. Indeed, say thirty years ago, professional mathematicians were a bit scared, as it were, of computers, but it seems to me that for experimentation and heuristic indications or suggestions, it is a marvelous tool. In fact, the meeting* that is going on right now, to a large extent, is possible because so much has been discovered experimentally. And Ulam (I'm happy to say (as a computer scientist :)) concurs: >So in physics, experiments lead finally to problems and to theories. Experimentation in mathematics could be purely mental, of course, and it was largely so over the centuries, but now there is an additional wonderful tool. To which Feigenbaum, who is into computers too, adds: >Certainly one has learned now, or is at the first stage of really learning, how to do experiments on computers that can begin to furnish intuition for problems that otherwise were impenetrable. The new intuition then enables you to write a more analytical theory. Do you think there are problems that are so complex that you won't be able to get that kind of a handle on them? For example, maybe memory in a brain has no global structure, but rather entails nothing more than a million different distinctly stored things, and then you wouldn't write any theory for it but rather only simulate such a system on a computer. Do you think there may be some limitation to what kinds of things you can analyze? And Ulam responds: >It depends on what you call theory. I noticed you said the analytical method; it means that by habit and tradition you think that is the only way to make progress in pure mathematics. Well it isn't. There may be some eventual super effect from the use of computers. I was involved from the beginning in computers and in the first experiments done in Los Alamos. Even in pure number theory there were already tiny little amusements from the first. A time may come, especially because the overspecialization of mathematics is increasing so much that it is impossible now to know more than a small part of it, that there will be a different format of mathematical thinking in addition to the existing one and a different way of thinking about publications. Maybe instead of publishing theorems and listing them there will be a sort of larger outline of whole theories, and individual theorems will be left to computers or to students to work out. It is conceivable. And here Kac brings up the advantage of computers for simulating new things: >Well, computers play a multiple role: they are superb as tools, but they also offer a field for a new kind of experimentation. Mitchell should know. There are certain experiments you cannot perform in your mind. It is impossible. There are experiments that you can do in your mind, and there are others you simply can't, and then there is a third kind of experiment where you create your own reality. Let me give you a problem of simple physics: a gas of hard spheres. Now nature did not provide a gas of hard spheres. Argon comes close, but you can always argue that maybe, because of slight attractive tails, something is going to happen. There is no substance-nature was so mean to us that there is no gas of hard spheres. And it poses very many interesting problems. It is child's play on the computer to create a gas of hard spheres. True, the memories are limited, so that, as a result, we can't have hard spheres, but we can have thousands of them, and actually the sensitivity to Avogadro's number is not all that great. We can really learn something about reality by creating an imitation of reality, which only the computer can do. That is a completely new dimension in experimentation. At this point, it seems Kac is talking about [[Domain Specific Languages (DSLs)|https://en.wikipedia.org/wiki/Domain-specific_language]] (decades before [[Martin Fowler|http://martinfowler.com/books/dsl.html]] and others) (!): >Sidney Brenner said that perhaps theory in biology will not be like that of physics. Rather than being a straight deductive, purely mathematical analytical theory, it may be more like answering the following question. You have a computer, and you don't know the wiring diagram, but you are allowed to ask it all sorts of questions. Then you ask the questions, and the computer gives you answers. From this dialogue you are to discover its wiring diagram. In a certain sense, he felt that the area of computer science-languages, theories of programming, what have you-may be more of a model for theorizing in biology than writing down analytic equations and solving them. (A more synthetic notion.) And evolutionary programming (or genetic algorithms) (!): >In fact, I think we will go even farther in this direction if we introduce, somehow, the possibility of evolution in machines, because you cannot understand biology without evolution. In fact, my colleague Gerry Edelman, whom you know very well and who is a Nobel laureate in biochemistry, is now "into the brain" and is trying to build a computer that has the process of evolution built into it so that you evolve programs: you start with one program that evolves into another, etc. It is an attempt to get away from the static, all-purpose Cray, or whatever it is, and to endow the computer with that one extraordinary, important element of life, namely evolution. And here, Ulam observes about the difference between mathematicians and physicists: >''Mathematicians start with axioms and draw consequences, theorems. Physicists have theorems or facts, observed by experiment, and they are looking for axioms, that is to say, laws of physics, backwards. So in physics the idea is to deduce this system of laws or axioms from which the observed things would follow. ''
We are masters of the unsaid words, but slaves of those we let slip out.
John Seely Brown (former Chief Scientist of Xerox Corporation and former director of the Xerox Palo Alto Research Center (PARC)) talked ([[slides|http://johnseelybrown.com/sensemaking.pdf]]) about what it means (and how the meaning changed) to make sense and learn in the new environment we are in, in his talk [[Sense-making and learning in the new 21st century environment]].
!On lifelong, spiraling discovery and learning
{{imgquote}} @@font-size:12pt;It’s more like a corkscrew than a path!@@
:: — Alice (Lewis Carroll in //Through the Looking Glass//, [[chapter 2|https://ebooks.adelaide.edu.au/c/carroll/lewis/looking/chapter2.html]])
"""
"""
{{imgquote}}
"""
We shall not cease from exploration
And the end of all our exploring
Will be to arrive where we started
And know the place for the first time.''*''
"""
:: — T.S. Eliot, The Four Quartets, [[Little Gidding|http://www.davidgorman.com/4Quartets/4-gidding.htm]].
"""
"""
::: ''*'' but as [[Terry Pratchett|https://www.terrypratchettbooks.com/sir-terry/]] had written (in [[A Hat Full of Sky|http://discworld.wikia.com/wiki/A_Hat_Full_of_Sky]]): ''Coming back to where you started is not the same as never leaving.''
"""
"""
<html>
<table class="borderless" border="0">
<tr border="0">
<td width="60%" border="0">
I imagine learning as a //spiral// of discovery^^1^^ (and [[re-discovery|Rediscovery]]): you may visit domains and topics again (and again), but you do it at a deeper (or higher, depending on your point of view^^2^^ :) level in every iteration.
</td>
<td width="100%" height="100%" border="0" >
<a href="./resources/spiral1.jpg" target="new"><img src="./resources/spiral1 1.png" /></a><br>
([["more spirals"|https://www.contextfreeart.org/gallery/search.php?t=tags&tag=spiral]])
</td>
</tr>
</table>
</html>
"""
"""
To paraphrase [[Douglas Hofstadter]] (from his wonderful book [[Gödel, Escher, Bach|https://en.wikipedia.org/wiki/G%C3%B6del,_Escher,_Bach]]) [[describing|Stepping Out]] the widening of the spiral of discovery:
: {{imgquote}} A learner is always trying to understand more deeply what they are, and the environment they live in, by stepping more and more out of what they see themselves to be and the context they believe themselves to be in, by breaking every rule and convention which they perceive themselves to be chained by.
Somewhere along this elusive path may come enlightenment. In any case (as I see it), the hope is that by gradually deepening one's awareness and knowledge, by gradually widening the scope of the "known domain", one will at the end^^3^^ come to a feeling of being at one with the entire universe.
I think that
[[M.C. Escher|http://www.mcescher.com/]], in his [ext["Drawing Hands"|./resources/escher_hands.jpg]], illustrates the nature of spiraling improvement/learning well: we initiate, explore, learn from the environment as well as from ourselves, influence the environment as well as get influenced by it, in successive cycles of refinement, meanings, and abilities.
"""
"""
Or, as the [[poet|About me]] said :)
<html>
<table class="borderless" border="0">
<tr>
<td width="60%">
`
We are alive,
... always learning
about the world around us
and about ourselves.
Actually, ...
learning about how it feels
and what it means
to be alive,
... always learning
about the world around us
and about ourselves.
Actually, ...
learning about how it feels
and what it means
to be alive,
...
`
</td>
<td width="100%" height="90%" >
<a href="./resources/escher_hands.jpg" target="new"><img src="./resources/escher_hands_1.jpg" width="100%" height="100%" /></a>
</td>
</tr>
</table>
</html>
"""
"""
Click the image below to see Spiraling Discovery in action (10MB .mov)
<a href="./resources/escher_print_gallery_loop_1.mpg" target="new"><img src="./resources/escher_gallery_1.jpg" width="25%" height="25%" /></a>
[[Escher's Print Gallery]] (from [[Escher and the Droste effect|http://escherdroste.math.leidenuniv.nl/index.php?menu=animation]] at the Leiden University in the Netherlands)
"""
"""
{{imgquote}} @@font-size:12pt;The most exciting phrase to hear in education, the one that heralds new discoveries, is not "Eureka!", but "That's funny...".@@
:: — [[Isaac Asimov|http://www.asimovonline.com/asimov_home_page.html]] (paraphrased)
"""
"""
So, here's to a journey of discovery and learning. It should be [[exciting and fun|https://www.goodreads.com/quotes/4061-the-most-exciting-phrase-to-hear-in-science-the-one]] (as [[Isaac Asimov|http://www.asimovonline.com/asimov_home_page.html]] put it, or at least [[the Unix fortune database|https://github.com/bmc/fortunes/blob/master/fortunes]] [[attributes|https://quoteinvestigator.com/2015/03/02/eureka-funny/]] it to him :)
"""
"""
!!!On Full-Mindedness and Mind-Fullness
I believe that one can be both [[Full-Minded|Full-Mindedness]] (i.e., full of knowledge about many things in the world) //and// [[Mind-Full|Mind-Fullness]] (i.e., attentive to the relationships and small details in our world).
It does not have to be ''either-this-or-that'' (i.e., either "Big Picture" or "minute details"), but can actually be ''both-this-and-that'' [[(if I say so myself... :)|Given a glass with water up to the mid level, people from The West will either say it's half full or they'll say it's half empty. People from The East will say it's both half full and half empty. They are all right.]], and that this is the beauty of the human experience (AKA, life)!
"""
"""
----
^^1^^ //Who// is discovering and //what// is discovered are actually //not// obvious questions.^^4^^
^^2^^ and as the "[[CS Sage|https://en.wikipedia.org/wiki/List_of_computer_scientists]]" [[Alan Kay|https://en.wikipedia.org/wiki/Alan_Kay]] quipped: A good point of view is worth many IQ points.
^^3^^ I'm not so sure about the end-state vision. Maybe we need to settle on the [[not-knowing state|I can live with doubt and uncertainty and not knowing. I think it's much more interesting to live not knowing than to have answers which might be wrong.]] Richard Feynman referred to, which may be "naturally perfect".
^^4^^ As [[Niels Bohr|https://en.wikipedia.org/wiki/Niels_Bohr]] quipped: A physicist is just an atom's way of looking at itself.^^5^^
^^5^^ But what (really) is an atom? Quantum Mechanics is a bit "[[fuzzy|http://cds.cern.ch/record/518511/files/0107054.pdf]]" about it, and even [[Richard Feynman|https://en.wikipedia.org/wiki/Richard_Feynman]] (no less) commented on it: If you think you understand quantum mechanics, you don't understand quantum mechanics.
<html>
Visitors: <a href="https://smallseotools.com/visitor-hit-counter/" target="_blank" title="Visitor Hit Counter">
<img src="https://smallseotools.com/counterDisplay?code=9d5e3d5d8fdbc3ecd083922207407aad&style=0005&pad=4&type=ip&initCount=586" title="Visitor Hit Counter" Alt="Visitor Hit Counter" border="0">
</a>
</html>
[[TiddlyWiki |https://classic.tiddlywiki.com/]] v.<<version>>
"""
"""
<html>
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-nc-sa/3.0/us/88x31.png" /></a><br />To the extent possible and under my control, this work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/">Creative Commons Attribution-NonCommercial-ShareAlike 3.0 United States License</a>.
</html>
!!!On lifelong, spiraling discovery I once had held the view that life's journey of discovery 'should be' from Full-Mindedness (a lot of knowledge and insights, if viewed positively, or a lot of clutter and tangles, if viewed negatively) to Mind-Fullness (simplicity due to abstraction, wisdom due to depth). And that the [['traveler'|Traveler-Pilgrim]] will be somewhere along the path, ''either'' close to one state ''or'' the other. I now find myself looking at it more "inclusively": it's not ''either-this-or-that'', but rather ''both-this-and-that'' [[(if I say so myself...)|Given a glass with water up to the mid level, people from the West will either say it's half full or they'll say it's half empty. People from the East will say it's both half full and half empty. They are all right.]]. One has the ability to be ''both'' full-minded ''and'' mindful. And this is the beauty of the human experience (AKA, life)! As [[Douglas Hofstadter|Douglas Hofstadter]] said about [[widening the spiral of discovery|Stepping Out]]: the hope is that by gradually deepening one's self awareness, by gradually widening the scope of "the system", one will at the end come to a feeling of [[being at one with the entire universe|All inclusive]]. And, of course, the flip side view is that it is an endless journey (not a pilgrimage), where, as [[Richard Feynman said|I can live with doubt and uncertainty and not knowing. I think it's much more interesting to live not knowing than to have answers which might be wrong.]], we can and should be fine living with doubt, uncertainty, and not knowing. To compliment (not contradict, mind you) this view, [[Halford John Mackinder|Halford John Mackinder]] said: Knowledge is one. Its division into subjects is a concession to human weakness.^^1^^ (or John Steinbeck's more poetic, and more [[uplifting take on one-ness|The Log from the Sea of Cortez - one-ness]]). [>img[Escher Hands|./resources/escher_hands_1.jpg][./resources/escher_hands.jpg]] An illustration of [[spiraling discovery|The Paradox of Return]]^^2^^ and improvement is [[M.C. Escher's etching of one hand drawing another|resources/escher_hands.jpg]], which in turn draws and refines the first one. In his book [["Authentic Happiness"|Authentic Happiness - by Martin Seligman]] Martin Seligman quotes [[a poem by Marvin Levine|00 - Preface to Authentic Happiness]] capturing it nicely. It's interesting that the Greeks depicted change and evolution in a more "linear metaphor", where you learn (and get wet) even if it feels like you are "[[immersed in the ''same'' river|No man ever steps in the same river twice, for it's not the same river and he's not the same man.]]". On the other hand, the Romans (or at Least [[Pliny the Elder|https://en.wikipedia.org/wiki/Pliny_the_Elder]]), thought in terms of "circles": Pliny had essentially invented the genre of the encyclopedia. Pliny did not use the term, but [[Sir Thomas Browne|https://en.wikipedia.org/wiki/Thomas_Browne]] did. It comes from a misreading of the Greek phrase enkyklios paideia—literally, “circular education.” The circle in question is not that of circular reasoning but, rather, the kind we have in mind when we talk about a “well-rounded education.” It's also interesting, and [[Joy Williams very nicely captured it|#83 - by Joy Williams]], that (at least some) North American Indian tribes thought of time as cyclical and overlapping (not sure if spiraling though). This idea is also echoed [[On Yin-Yang Polarity - by Alan Watts]]. So, here's to a journey of discovery [[(re-discovery?)|Rediscovery]] and learning. It should be exciting and fun, or as [[Isaac Asimov|http://www.asimovonline.com/asimov_home_page.html]] put it nicely: The most exciting phrase to hear in science, the one that heralds new discoveries, is not "Eureka!", but "That's funny...". ---- ^^1^^ Bertrand Russell expressed a similar idea: //Matter is less material and mind is less spiritual than is generally supposed. The habitual separation of physics and psychology, mind and matter is metaphysically indefensible.// ^^2^^ It is an important question of //who// is discovering and //what// is discovered.^^3^^ ^^3^^ Or as Niels Bohr quipped: A physicist is just an atom's way of looking at itself.^^4^^ ^^4^^ But what (really) is an atom? The same Bohr also said: Anyone who is not shocked by quantum theory has not understood it.^^5^^ ^^5^^ on which Richard Feynman (no less!) commented: If you think you understand quantum mechanics, you don't understand quantum mechanics. <html> <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-nc-sa/3.0/us/88x31.png" /></a><br />To the extent possible and under my control, this work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/">Creative Commons Attribution-NonCommercial-ShareAlike 3.0 United States License</a>. </html>
Wernher Magnus Maximilian Freiherr von Braun (March 23, 1912 June 16, 1977) was a German rocket scientist, engineer, space architect, and one of the leading figures in the development of rocket technology in Nazi Germany and the United States during and after World War II.
<<list-links "[tag{!!title}]">>
In an [[Op-Ed column in the New York Times|http://www.nytimes.com/2013/02/19/opinion/brooks-what-data-cant-do.html]], columnist David Brooks brought up a few good points about why (and when) to be cautious about pure data analysis (or Big Data "number crunching") results/conclusions. * __Data struggles with the social.__ Computers are excellent with number crunching, and unlike brains, are very poor in social cognition. >People are really good at mirroring each other’s emotional states, at detecting uncooperative behavior and at assigning value to things through emotion. Computer-driven data analysis, on the other hand, excels at measuring the quantity of social interactions but not the quality. * __Data struggles with context.__ Life does not consist of a series of disconnected events. Life is a mesh of events and situations, embedded in sequences and contexts. The human brain has evolved to account for this reality. >[Machines are pretty bad] at telling stories that weave together multiple causes and multiple contexts. * __Data creates bigger haystacks.__ This does not necessarily produce more needles. >As we acquire more data, we have the ability to find many, many more statistically significant correlations. Most of these correlations are spurious and deceive us when we’re trying to understand a situation. Falsity grows exponentially the more data we collect. * __Big data has trouble with big problems.__ Brooks is fuzzy on this point, and just argues that usually, Big Problems cannot be solved by running experiments with control groups and alternative scenarios. True, but this doesn't necessarily preclude using Big Data approaches as part of a cautious path to a solution. This point could be supporting the point about machines having a problem with contexts, since big problems are usually big because they are multi-faceted, involving multiple contexts, situations, disciplines, which computation/data cannot handle well (yet?). * __Data favors memes over masterpieces.__ Using data analysis (too early in the process?) may give erroneous impressions and force wrong conclusions, since in some situations (in the cases of masterpieces), crowds (and therefore, crowdsourcing, and big data analysis) may not like/appreciate/accept/embrace something that //later// may turn out to be of high value/quality. ** Also (and this is my addition/supplementation), this may be similar to how quarterly financial/business results tend to drive businesses today, favoring the short term over the long term, and possibly not serving well customers, employees, shareholders, and humanity. *__Data obscures values.__ >data is never raw; it’s always structured according to somebody’s predispositions and values. The end result looks disinterested, but, in reality, there are value choices all the way through, from construction to interpretation. __And Brooks' bottom line__ is not surprising: you always want to use the right tool for the right job to get the best results :) >This is not to argue that big data isn’t a great tool. It’s just that, like any tool, it’s good at some things and not at others.
WHAT HAVE YOU CHANGED YOUR MIND ABOUT? Copyright 2009 by [[Edge Foundation, Inc.|http://edge.org/]]
Today's leading minds rethink everything.
Edited by John Brockman
<<forEachTiddler
where
'tiddler.tags.contains("book-chapter") && tiddler.tags.contains("What Have You Changed Your Mind About?")'
sortBy
'tiddler.title'>>
[[Also by John Brockman and the Edge "cohort"|Is the Internet Changing the Way You Think?]]
In an [[insightful article about Daniel Kahneman|https://jasonzweig.com/what-i-learned-from-daniel-kahneman/]] (of the "Dynamic Duo" Kahneman & Tversky :), Jason Zweig writes a telling anecdote. (Zweig's article (see [[local summary|Investment insights from Daniel Kahneman (through Jason Zweig)]]) about what he learned from Kahneman about investing ([[Do You Sabotage Yourself?|https://jasonzweig.com/from-the-archives-daniel-kahneman/]]) is also very insightful (and 'most excellent' :) ) Besides showing Kahneman's wisdom and humility, his story also shows yet another example of a proven, effective (but hard!) way to produce/write high quality content. What struck me about Kahneman's way of thinking/working/writing is how it so beautifully applies to software development. Prototyping (of software code) and creating a draft (of a document) are in principle, the same good (and 'most excellent' :) way to deal with our human limitations, in the effort to produce high quality results. A few "[[CS Sages|https://en.wikipedia.org/wiki/List_of_computer_scientists]]" observed about writing (a good software program (or a good content)): >(Fred Brooks, on developing software "throw-away prototypes") plan to throw one away; you will, anyhow. >(Ken Thompson) You don't have to optimize what you don't write. The most powerful optimization tool in existence //may// be the delete key. >(Rob Pike) People are reluctant to throw away the visible product of lots of work, but doing a good job often means building afresh rather than complicating old programs by adding new features. >(C.A.R. Hoare) There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. So now that the "asides" and "parallels" are out of the way, here's Zweig's anecdote: In the nearly two years that I worked with Danny on the book that became "Thinking, Fast and Slow", many things amazed me about this man whom I had believed I already knew well: his inexhaustible mental energy, his complete comfort in saying “I don’t know,” his ability to wield a softly spoken “Why?” like the swipe of a giant halberd [a combined spear and battleaxe] that could cleave overconfidence with a single blow. But nothing amazed me more about Danny than his ability to detonate what we had just done. Anyone who has ever collaborated with him tells a version of this story: You go to sleep feeling that Danny and you had done important and incontestably good work that day. You wake up at a normal human hour, grab breakfast, and open your email. To your consternation, you see a string of emails from Danny, beginning around 2:30 a.m. The subject lines commence in worry (something like “I don’t think this works”), turn darker (“What were we thinking?”), and end around 5 a.m. in a barrage of panic (“This will not do at all”) and despair (“This is just garbage”). You send an email asking when he can talk; you assume Danny must be asleep after staying up all night trashing the chapter. Your cellphone rings a few seconds later. “I think I figured out the problem,” says Danny, sounding remarkably chipper. “What do you think of this approach instead?” The next thing you know, he sends a version so utterly transformed that it is unrecognizable: It begins differently, it ends differently, it incorporates anecdotes and evidence you never would have thought of, it draws on research that you’ve never heard of. If the earlier version was close to gold, this one is hewn out of something like diamond: The raw materials have all changed, but the same ideas are somehow illuminated with a sharper shift of brilliance. The first time this happened, I was thunderstruck. How did he do that? How could anybody do that? When I asked Danny how he could start again as if we had never written an earlier draft, he said the words I’ve never forgotten: “I have no sunk costs.” To most people, rewriting is an act of cosmetology: You nip, you tuck, you slather on lipstick. To Danny, rewriting is an act of war: If something needs to be rewritten then it needs to be destroyed. The enemy in that war is yourself. Having wanted to be a writer since I was 13, I still hadn’t learned how to be one until I worked with Danny. I no longer try to fix what I’ve just written if it doesn’t work. I try to destroy it instead — and start all over as if I had never written a word. Danny taught me that you can never create something worth reading unless you are committed to the total destruction of everything that isn’t. He taught me to have no sunk costs. """ """ Now, do I (or most programmers and/or writers) always follow this advice? Of course not. It's hard (and sometimes (often?) unnecessary (or that's at least what we tell ourselves :)). ''BUT'', I know I never regretted doing this, whenever I did!
From a strong leader, the founder and former CEO of the Visa credit card association, [[Dee Hock|http://www.deewhock.com/#intro]]^^1^^, in his paper [["The Art of Chaordic Leadership"|http://www.meadowlark.co/the_art_of_chaordic_leadership_hock.pdf]]^^2^^ : >Management inevitably is viewed as exercise of authority -- with selecting employees, motivating them, training them, appraising them, organizing them, directing them, controlling them. That perception is mistaken. > * ''The first and paramount responsibility'' of anyone who purports to manage is to manage self: one's own integrity, character, ethics, knowledge, wisdom, temperament, words, and acts. It is a complex, unending, incredibly difficult, oft-shunned task. We spend little time and rarely excel at management of self precisely because it is so much more difficult than prescribing and controlling the behavior of others. ** Hock suggests devoting 50% to this. * ''The second responsibility'' is to manage those who have authority over us: bosses, supervisors, directors, regulators, ad infinitum. Without their consent and support, how can we follow conviction, exercise judgment, use creative ability, achieve constructive results or create conditions by which others can do the same? Managing superiors is essential. ** Hock suggests devoting 25% to this. * ''The third responsibility'' is to manage one's peers -- those over whom we have no authority and who have no authority over us -- associates, competitors, suppliers, customers -- one's entire environment if you will. Without their respect and confidence little or nothing can be accomplished. Our environment and peers can make a small heaven or hell of our life. ** Is it not wise to devote at least 20% of our time, energy, and ingenuity to managing them? * if one has attended to self, superiors, and peers there is nothing else left. Obviously, ''the fourth responsibility'' is to manage those over whom we have authority. The common response is that all one's time will be consumed managing self, superiors and peers [50% + 25% + 20% respectively]. There will be no time to manage subordinates. Exactly! One need only select decent people, introduce them to the concept, induce them to practice it, and enjoy the process. > If those over whom we have authority properly manage themselves, manage us, manage their peers, and replicate the process with those they employ, what is there to do but see they are properly recognized, rewarded -- and stay out of their way?It is not making better people of others that leadership is about. In today's world effective leadership is chaordic. It's about making a better person of self. Income, power and position have nothing to do with that. In fact, they often interfere with it. ---- ^^1^^ - I think that Hock was cut from the same cloth as another great businessman and leader -- [[Robert Townsend]], who was also [[very direct about character and management|If you have to have a policy manual, publish the Ten Commandments.]] ^^2^^ - As Hock explains it: By chaord, I mean any self-organizing, self governing, adaptive, nonlinear, complex organism, organization, community or system, whether physical,biological or social, the behavior of which harmoniously blends characteristics of both chaos and order. Loosely translated to business, it can be thought of as an organization that harmoniously blends characteristics of competition and cooperation; or from the perspective of education, an organization that seamlessly blends theoretical and experiential learning.
[[Robert Logan|http://www.physics.utoronto.ca/people/homepages/logan/]] in his book //What is Information?// tackles the questions about the nature of information.
(his book [[The Sixth Language: Learning a Living in the Internet Age|New languages]] is also applicable to information, knowledge, learning, and technology)
In the [ext[second chapter of the book|resources/logan_information_ch2.pdf]] Logan starts by giving 5 different definitions of the term information:
> We have represented a discrete information source as a Markoff process. Can we define a quantity, which will measure, in some sense, how much information is produced by such a process, or better, at what rate information is produced? - Shannon (1948)
> To live effectively is to live with adequate information - Wiener (1950)
> Information is a distinction that makes a difference - ~MacKay (1969)
> Information is a difference that makes a difference - Bateson (1973)
> Information arises as natural selection assembling the very constraints on the release of energy that then constitutes work and the propagation of organization - Kauffman, Logan, Este, Goebel, Hobill & Shmulevich (2007)
I am a big admirer of Shannon, and I like Logan's elaboration on (or alternative definition of) information:
>the beginning of the modern theoretical study of information is attributed to Claude Shannon (1948), who is recognized as the father of information theory. He defined information as a message sent by a sender to a receiver. Shannon worked at Bell Labs and wanted to solve the problem of how to best encode information that a sender wished to transmit to a receiver. Shannon gave information a numerical or mathematical value based on probability defined in terms of the concept of information entropy more commonly known as Shannon entropy. Information is defined as the measure of the decrease of uncertainty for a receiver. The amount of Shannon information is inversely proportional to the probability of the occurrence of that information, where the information is coded in some symbolic form as a string of 0s and 1s or in terms of some alphanumeric code.
And to the question of the difference between data, information, knowledge, and wisdom:
> __Data__ are the pure and simple facts without any particular structure or organization, the basic atoms of information,
> __Information__ is structured data, which adds meaning to the data and gives it context and significance,
> __Knowledge__ is the ability to use information strategically to achieve one's objectives, and
> __Wisdom__ is the capacity to choose objectives consistent with one's values and within a larger social context (Logan and Stokes 2004, pp. 38-39).
Regarding __data__ vs. __information__ as described on Wikipedia (9/12/2007):
>Even though information and data are often used interchangeably, they are actually very different. Data is a set of unrelated information, and as such is of no use until it is properly evaluated. Upon evaluation, once there is some significant relation between data, and they show some relevance, then they are converted into information. Now this same data can be used for different purposes. Thus, till the data convey some information, they are not useful.
Logan makes a very interesting observation regarding "making information out of data", that aligns with ~MacKey's and Bateson's definitions above, comparing it to Shannon's ("stripped, bare-boned) definition. He indicates that the necessity of the context __makes information an emergent phenomenon!__
>The contextualization of data so that it has meaning and significance and hence operates as information is an emergent phenomenon. The communication of information cannot be explained solely in terms of the components of the Shannon system consisting of the sender, the receiver and the signal or message. It is a much more complex process than the simplified system that Shannon considered for the purposes of mathematizing and engineering the transmission of signals. First of all it entails the knowledge of the sender and the receiver, the intentions or objectives of the sender and the receiver in participating in the process and finally the effects of the channel of communication itself independent of its content as in ~McLuhan's observation that the medium is the message . The knowledge and intention of the sender and the receiver as well as the effects of the channel all affect the meaning of the message that is transmitted by the signal in addition to its content.
This is a strong statement about the __non-materiality of information__, which is Logan covers towards the end of chapter 2:
>The Materiality of Information in Biotic Systems Information is information, not matter or energy. No materialism which does not admit this can survive at the present day. - Norbert Wiener (1948)
>Shannon's theory defines information as a probability function with no dimension, no materiality, and no necessary connection with meaning. It is a pattern not a presence. Hayles (1999a, p. 18)
by Kevin Kelly, Viking press, 2010
<<forEachTiddler
where
'tiddler.tags.contains("book-chapter") && tiddler.tags.contains("What Technology Wants")'
sortBy
'tiddler.title'>>
When fishing for happiness, catch and release. -- from Shimon Edelman's book "The Happiness Pursuit" (also wrote a good book on human neuroscience and perception called //Computing the Mind: How the Mind Really Works//)
When ideas fail, words come in very handy.
When I design a new module or lesson or demo in my computer science curriculum, I often run into the considerations and balancing between correctness, clarity, elegance, and performance (resource utilization).
These are important to consider in both the educational context/sphere, and in industry/production, since they are "big truths" or at least "important principles" of [[The Art|Computer programming is an art, because it applies accumulated knowledge to the world, because it requires skill and ingenuity, and especially because it produces objects of beauty. A programmer who subconsciously views himself as an artist will enjoy what he does and will do it better.]]!
Some people see these as an exercise in compromising and trade-offs, but I think that this is an unfortunate misunderstanding, as it has the potential to sacrifices important aspects of an artifact (program, system, project, etc.) for equally important other aspects.
I see it as another case of "[[it's not either or, but both this and that|Given a glass with water up to the mid level, people from The West will either say it's half full or they'll say it's half empty. People from The East will say it's both half full and half empty. They are all right.]]". Ideally, it's a process/journey, where you start by making sure what you are doing (designing and coding) is correct, but you don't ignore elegance/resource-utilization and performance aspects. Once "it works" you focus more on "beauty" (which you did not neglect (!) during the previous phase of the development) and still don't ignore performance, and still make sure it is correct. And then move on to making it fast (while not "uglifying" it, and keeping it working, of course :)
This debate often turns into "religious wars" between professionals and experts, and what I (often) find is that their disagreements come from not understanding each other's context or point of view (and as the "[[CS Sage|https://en.wikipedia.org/wiki/List_of_computer_scientists]]" Alan Kay quipped: [[A good point of view is worth many IQ points]].).
As is typical in these kinds of (heated) arguments (of rational people :), each side brings viewpoints and quotes from various "[[CS Sages|https://en.wikipedia.org/wiki/List_of_computer_scientists]]", one of which is Donald Knuth, whose canonical work is "[[The Art of Computer Programming|https://en.wikipedia.org/wiki/The_Art_of_Computer_Programming]]".
[[Knuth is very big on both elegance/style AND performance/resource-utilization|On computer program elegance]], but as is often true, people on each side of the argument pick and choose more of one or the other (again, compromising/trading-off).
For example, Knuth is often quoted as saying:
>We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil.
What many of those using this quote (innocently or on purpose) leave out is the next sentence, as well as the full context ([[Structured Programming With Go To Statements|http://wiki.c2.com/?StructuredProgrammingWithGoToStatements]] of all things :) in which it had been said:
>Programmers waste enormous amounts of time thinking about, or worrying about, the speed of noncritical parts of their programs, and these attempts at efficiency actually have a strong negative impact when debugging and maintenance are considered. We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. __Yet we should not pass up our opportunities in that critical 3%.__
Moreover, Knuth, in the same article, makes it very clear how he looks at performance optimization, and he's definitely not giving it the evil eye :)
>The improvement in speed from Example 2 to Example 2a is only about 12%, and many people would pronounce that insignificant. The conventional wisdom shared by many of today’s software engineers calls for ignoring efficiency in the small; but I believe this is simply an overreaction to the abuses they see being practiced by penny-wise- and-pound-foolish programmers, who can’t debug or maintain their “optimized” programs. In established engineering disciplines a 12% improvement, easily obtained, is never considered marginal; and I believe the same viewpoint should prevail in software engineering. Of course I wouldn’t bother making such optimizations on a one-shot job, but when it’s a question of preparing quality programs, I don’t want to restrict myself to tools that deny me such efficiencies.
But, what Knuth does say is that [[elegance, clarity, style are also very important|On computer program elegance]] (they are actually at the core of what he strongly claims is [[an Art|Computer programming is an art, because it applies accumulated knowledge to the world, because it requires skill and ingenuity, and especially because it produces objects of beauty. A programmer who subconsciously views himself as an artist will enjoy what he does and will do it better.]]).
And [[The Zen of Python|https://www.python.org/dev/peps/pep-0020/]] (another example) is also clear on needing to tend to ''all'' aspects:
* Beautiful is better than ugly. Readability counts. ("beauty", "elegance")
* Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. ("performance" and "beauty")
* Special cases aren't special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. (mainly "correctness", but also "performance")
You get the point.
It seems obvious that in an educational context, correctness ("make it work") is the most important aspect of a program/project/demo/lesson, __tightly coupled__ with clarity/readability/elegance ("make it beautiful"). It is vital to make things as simple ([[as possible, but not simpler|http://quoteinvestigator.com/2011/05/13/einstein-simple/]]), streamlined, clear, and understandable as possible, or else the whole point may be missed by the learner (and correctness, at that point is a mute point, to a large extent).
At the risk of sounding "terribly uneducational", I would say that in a learning context, I feel that it's OK to be "not entirely correct" (or "over simplify", at least at the beginning) in order to achieve clarity, rather than be "perfectly correct" but not very clear/clean/readable/understandable.
I think that it's also clear that (again, at least in an educational context) one should (at least initially) sacrifice performance/elegance for better clarity.
But the teacher (and craftsman) should keep in mind that this is a journey, and an important point throughout the learning experience should be the //exposure// of learners to all these aspects/phases, not treating any of them as "extra" or "afterthought", because this is "robbing" learners of beauty/elegance/understanding/performance/joy, and causing harm in a production/industry context.
From [[Hannah Fry|http://www.hannahfry.co.uk/]]'s book [["Hello World"|https://browsermedia.agency/blog/book-review-hello-world-hannah-fry/]]: WHEN I WAS 7 years old, my dad brought a gift home for me and my sisters. It was a ZX Spectrum, a little 8-bit computer – the first time we’d ever had one of our own. It was probably already five years out of date by the time it arrived in our house, but even though it was second-hand, I instantly thought there was something marvellous about that dinky machine. The Spectrum was roughly equivalent to a Commodore 64 (although only the really posh kids in the neighbourhood had one of those) but I always thought it was a far more beautiful beast. The sleek black plastic casing could fit in your hands, and there was something rather friendly about the grey rubber keys and rainbow stripe running diagonally across one corner. For me, the arrival of that ZX Spectrum marked the beginning of a memorable summer spent up in the loft with my elder sister, programming hangman puzzles for each other, or drawing simple shapes through code. All that ‘advanced’ stuff came later, though. First we had to master the basics. Looking back, I don’t exactly remember the moment I wrote my first ever computer program, but I’m pretty sure I know what it was. It would have been the same simple program that I’ve gone on to teach all of my students at University College London; the same as you’ll find on the first page of practically any introductory computer science textbook. Because there is a tradition among all those who have ever learned to code – a rite of passage, almost. Your first task as a rookie is to program the computer to flash up a famous phrase on to the screen: ‘HELLO WORLD’ It’s a tradition that dates back to the 1970s, when [[Brian Kernighan]] included it as a tutorial in his phenomenally popular programming textbook.^^1^^ The book – and hence the phrase – marked an important point in the history of computers. The microprocessor had just arrived on the scene, heralding the transition of computers from what they had been in the past – enormous great specialist machines, fed on punch cards and ticker-tape – to something more like the personal computers we’re used to, with a screen, a keyboard and a blinking cursor. ‘Hello world’ came along at the first moment when chit-chat with your computer was a possibility. Years later, Brian Kernighan told a Forbes interviewer about his inspiration for the phrase. He’d seen a cartoon showing an egg and a newly hatched chick chirping the words ‘Hello world!’ as it was born, and it had stuck in his mind. It’s not entirely clear who the chick is supposed to be in that scenario: the fresh-faced human triumphantly announcing their brave arrival to the world of programming? Or the computer itself, awakening from the mundane slumber of spreadsheets and text documents, ready to connect its mind to the real world and do its new master’s bidding? Maybe both. But it’s certainly a phrase that unites all programmers, and connects them to every machine that’s ever been programmed. There’s something else I like about the phrase – something that has never been more relevant or more important than it is now. As computer algorithms increasingly control and decide our future, ‘Hello world’ is a reminder of a moment of dialogue between human and machine. Of an instant where the boundary between controller and controlled is virtually imperceptible. It marks the start of a partnership – a shared journey of possibilities, where one cannot exist without the other. In the age of the machine, that’s a sentiment worth bearing in mind. ‐----------------- 1 The C Programming Language by Kernighan and Ritchie 1978.
In an article titled [["Writing is a Technology that Restructures Thought"|http://worrydream.com/refs/Ong%20-%20Writing%20is%20a%20Technology%20that%20Restructures%20Thought.pdf]], Walter J. Ong writes: >Writing, Plato has Socrates say in the Phaedrus, is inhuman, pretending to establish outside the mind what in reality can only be in the mind. Writing is simply a thing, something to be manipulated, something inhuman, artificial, a manufactured product. We recognize here the same complaint that is made against computers: they are artificial contrivances, foreign to human life. > >Secondly, Plato's Socrates complains, a written text is basically unresponsive. If you ask a person to explain his or her statement, you can get at least an attempt at explanation: if you ask a text, you get nothing except the same, often stupid words which called for your question in the first place. In the modern critique of the computer, the same objection is put, 'Garbage in, garbage out'. >So deeply are we into literacy that we fail commonly to recognize that this objection applies every hit as much to books as to computers. If a book states an untruth, ten thousand printed refutations will do nothing to the printed text: the untruth is there for ever. This is why books have been burnt. Texts are essentially contumacious. > >Thirdly, Plato's Socrates urges, writing destroys memory. Those who use writing will become forgetful, relying on an external source for what they lack in internal resources. Writing weakens the mind. > >Today, some parents and others fear that pocket calculators provide an external resource for what ought to be the internal resource of memorized multiplication tables. Presumably, constant repetition of multiplication tables might produce more and more Albert Einsteins. Calculators weaken the mind, relieve it of the setting-up exercises that keep it strong and make it grow. (Significantly, the fact that the computer manages multiplication and other computation so much more effectively than human beings do, shows how little the multiplication tables have to do with real thinking.) > >Fourthly, in keeping with the agonistic [combative; polemical] mentality of oral cultures, their tendency to view everything in terms of interpersonal struggle, Plato's Socrates also holds it against writing that the written word cannot defend itself as the natural spoken word can: real speech and thought always exist essentially in the context of struggle. Writing is passive, out of it, in an unreal, unnatural world. So, it seems, are computers: if you punch the keys they will not fight back on their own, but only in the way they have been programmed to do. Those who are disturbed about Plato's misgivings about writing will be even more disturbed to find that print created similar misgivings when it was first introduced. Hieronimo Squarciafico, who in fact promoted the printing of the Latin classics, also argued in 1477 that already 'abundance of books makes men less studious' (Ong 1982: 80). Even more than writing does, print destroys memory and enfeebles the mind by relieving it of too much work (the pocket calculator complaint once more), downgrading the wise man and wise woman in favour of the pocket compendium. But Ong points out the irony in Plato's/Aristotle's objection/rejection of writing: >Plato's entire epistemology was unwittingly a programmed rejection of the archaic preliterate world of thought and discourse. This world was oral, mobile, warm, personally interactive (you needed live people to produce spoken words). It was the world represented by the poets, whom Plato would not allow in his Republic, because, although Plato could not formulate it this way, their thought processes and modes of expression were disruptive of the cool, analytic processes generated by writing. > >The Platonic ideas are not oral, not sounded, not mobile, not warm, not personally interactive. They are silent, immobile, in themselves devoid of all warmth, impersonal and isolated, not part of the human lifeworld at all but utterly above and beyond it, paradigmatic abstractions. Plato's term idea, form, is in fact visually based, coming from the same root as the Latin videre, meaning to see, and such English derivatives as vision, visible, or video. In the older Greek form, a digamma [the sixth letter of the early Greek alphabet, pronounced as “w”] had preceded the iota: videa or widea. > >Platonic form was form conceived of by analogy precisely with visible form. Despite his touting of logos and speech, the Platonic ideas in effect modelled intelligence not so much on hearing as on seeing. Ong points out something that we sometimes forget (or take for granted): writing __is__ a technology (and as he points out, a revolutionary one, at that): >In //From Memory to Written Record: England 1066-1307//, M. T. Clanchy (1979) has an entire chapter entitled 'The Technology of Writing'. He explains how in the West through the Middle Ages and earlier almost all those devoted to writing regularly used the services of a scribe because the physical labour writing involved-scraping and polishing the animal skin or parchment, whitening it with chalk, resharpening goose-quill pens with what we still call a pen-knife, mixing ink, and all the rest-interfered with thought and composition. > >Chaucer's 'Wordes unto Adam, His Owne Scriveyn' humorously expressed the author's resentment at having to 'rubbe and scrape' to correct his scribe Adam's own carelessness in plying his craft. Today's ballpoint pens, not to mention our typewriters and word processors or the paper we use, are high-technology products, but we seldom advert to the fact because the technology is concentrated in the factories that produce such things, rather than at the point of production of the text itself, where the technology is concentrated in a manuscript culture. > >Although we take writing so much for granted as to forget that it is a technology, writing is in a way the most drastic of the three technologies of the word: It initiated what printing and electronics only continued, the physical reduction of dynamic sound to quiescent space, the separation of the word from the living present, where alone real, spoken words exist. As a parallel aside/analogy: is the fact that nowadays every "literate person" knows how to write (unaided :) as foreteller of the future where every such person will know how to program a computer and make it do what they want it to do for them? :) And another irony (and a "strange human loop" :) of this powerful technology: >Once reduced to space, words are frozen and in a sense dead. Yet there is a paradox in the fact that the deadness of the written or printed text, its removal from the living human lifeworld, its rigid visual fixity, assures its endurance and its potential for being resurrected into limitless living contexts by a limitless number of living readers. The dead, thing-like text has potentials far outdistancing those of the simply spoken word. > >The complementary paradox, however, is that the written text, for all its permanence, means nothing, is not even a text, except in relationship to the spoken word. For a text to be intelligible, to deliver its message, it must be reconverted into sound, directly or indirectly, either really in the external world or in the auditory imagination. All verbal expression, whether put into writing, print, or the computer, is ineluctably bound to sound forever.
Steven Pinker, a prominent and prolific psycholinguist at Harvard, in his book //The Sense of Style: The Thinking Person’s Guide to Writing in the 21st Century//, writes about why style matters (See also [[99 writing styles by Raymond Queneau|Exercises in Style - Raymond Queneau]]): >Style, [...], adds beauty to the world. To a literate reader, a crisp sentence, an arresting metaphor, a witty aside, an elegant turn of phrase are among life’s greatest pleasures… This thoroughly impractical virtue of good writing is where the practical effort of mastering good writing must begin. It is interesting to compare (literature) writing style to (programming) coding style. Two "[[CS Sages|https://en.wikipedia.org/wiki/List_of_computer_scientists]]", Donald Knuth, and Edsger Dijkstra, were both thinking about, advocating and promoting computer program elegance (or style). But they had different takes on what it means and how to achieve it. In the article [[Bend Sinister|https://monoskop.org/images/1/14/Goriunova_Olga_ed_Fun_and_Software_Exploring_Pleasure_Paradox_and_Pain_in_Computing.pdf]] artist and programmer [[Simon Yuill|http://www.lipparosa.org/]] observes (about Knuth, first): >Here, art is that which defines the conditions under which knowledge becomes productive. For Knuth these conditions are both economic, the effective use of resources, and aesthetic, a sense for that which is harmonious and ‘good’. Bentham and Mill help define what may be described as Knuth’s ethics of production, the behaviours and moral values under which programming is practised. The realization of this in elegant code gives material shape to the larger project of Literate Programming which Knuth has advocated throughout his career and created software tools to facilitate. Just as these ethics draw upon the ideas of English liberal philosophers, Bentham and Mill, the practice of Literate Programming also adopts the aesthetic medium most closely related to the expression of liberal thinking, the essay: ‘The practitioner of literate programming can be regarded as an essayist, whose main concern is with exposition and excellence of style’. [and about Dijkstra:] >Dijkstra didn't like the term "programming language" and preferred the term "programming notation" and explained the difference, strength and danger: >>The introduction of the term ‘language’ in connection with notation techniques for programs has been a mixed blessing. On the one hand it has been very helpful in as far as existing linguistic theory now provided a natural framework and an established terminology (‘grammar’, ‘syntax’, ‘semantics’, etc.) for discussion. On the other hand we must observe that the analogy with (now so-called!) ‘natural languages’ has been very misleading, because natural languages, non-formalized as they are, derive both their weakness and their power from their vagueness and imprecision. >Although Dijkstra was as strong an advocate of elegance as Knuth, this comment indicates something of a distinction in how each understood this. While both might place emphasis upon the precise, efficient expression of an idea in code, for Knuth this has a rhetorical dimension in that code, as essay, should aim to be persuasive in expression and display an appropriate conduct on the part of the programmer [...]. For Dijkstra elegance lies more in an irrefutably self-evident correctness, for truly elegant code would not require commentary nor debugging. For Knuth elegance is the start of a conversation, for Dijkstra it is the conclusion.
In Computer Science, explaining (and even more so, understanding :) formal and actual function parameters is not easy.
So, for example, in Python, if you define a function called draw_square() thusly (assuming you have a graphics turtle library, and pencil is a turtle):
{{{
def draw_square():
pencil.pendown()
for side in range(4):
pencil.forward(100)
pencil.right(90)
}}}
you can call (use) this function and it will draw a square of size 100 (pixels) on each side.
If you want to draw squares of different sizes, you need to tell the draw_square() function what size you want, and you can do it by using what's called a parameter -- see the new function definition below):
{{{
def draw_square(length):
pencil.pendown()
for side in range(4):
pencil.forward(length)
pencil.right(90)
}}}
Now, every time you call (use) the function, you have to give it the value of the "length" parameter you want it to use when drawing a square:
So calling draw_square(50) will draw a square of 50 (pixels) on each side, and calling draw_square(100) will draw a square of 100 (pixels) on each side, like so:
{{{
# draw a small square:
side = 50
draw_square(side)
# and a larger square:
side = 100
draw_square(side)
}}}
Students often confuse the "side" variable which is used to input into the function the size of the square, and the "length" parameter which is used inside the function to actually draw it.
In formal programming, "side" is called a "actual parameter" and "length" is called the "formal parameter".
To make clearer what the difference is between "formal" and "actual" parameters, I use a "wild story", with the hope that the wildness will make the story (and it's meaning) stick in students' memory.
The wild story: let's say we have a custom (procedure, function) of greeting visitors to our CS lab. The first visitor showing up at the door is seated on one of the swiveling student chairs, and turned/swiveled around 3 times.
The second visitor showing up, is seated at the teacher's desk, and a pencil is stuck behind their ear.
In programming pseudo-code (almost-code :) this procedure/function can be __defines__ as:
{{{
def visiting_procedure(visitor_1, visitor_2):
seat visitor_1 on a swiveling chair
turn visitor_1 3 times
seat visitor_2 at teacher's desk
stick pencil behind visitor_2's ear
}}}
where visitor_1 and visitor_2 are the placeholders, standing for any 2 visitors.
(and the story continues:) Now suppose, the school principle (let's call her Jane) and the school administrator (let's call him Joe), show up at the door. What do we do? We __use__ our procedure/function:
We seat ''Jane'' on a swiveling char and turn her three times, and
we seat ''Joe'' at the teacher's desk and stick a pencil behind his ear.
So, in this exciting (and hopefully, memorable) fable, visitor_1 and visitor_2 are the "formal" parameters (the placeholders for the function), and Jane and Joe are the "actual" parameters (or values).
It turns out that this wild story (and the wilder the better?) helps students understand and correctly use formal parameters when defining a function, and apply actual parameters when calling/using it.
This may employ a technique/phenomenon also used for remembering long and arbitrary sequences of objects or facts.
* I just finished reading the book //Little, Big// by John Crowley, and I enjoyed it a lot! It's //wonder//ful! It has this "softly magical" feeling to it (it is a "fairytale" after all), and it contains "Prose that F. Scott Fitzgerald would envy... the best fantasy yet written by an American." (from the "Praise for" page of the book). In the book, Crowley talks about [[Giordano Bruno|http://en.wikipedia.org/wiki/Giordano_Bruno]], [[The art of memory|http://en.wikipedia.org/wiki/Art_of_memory]], and the mnemonic devices one of the characters (Ariel Hawksquill) is using to remember prodigious amounts of details and relationships.
Sir Winston Leonard Spencer Churchill, (30 November 1874 24 January 1965) was a British politician and statesman known for his leadership of the United Kingdom during the Second World War (WWII).
[[Winston Churchill|http://en.wikipedia.org/wiki/Winston_Churchill]]
<<list-links "[tag{!!title}]">>
A funny dialog between a wizard (named Wen) and his apprentice from the book [[The Thief of Time|http://www.chrisjoneswriting.com/thief-of-time.html]] by the inimitable [[Terry Pratchett]]:
"""
Wen: 'I have heard the heartbeat of the universe. I know the answers to many questions. Ask me.’
The apprentice gave him a bleary look. It was too early in the morning for it to be early in the morning. That was the only thing he currently knew for sure.
‘Er…what does master want for breakfast?’ he said.
Wen looked down on their camp and across the snowfields and purple mountains to the golden daylight creating the world, and mused upon certain aspects of humanity.
‘Ah,’ he said. ‘One of the difficult ones.'
"""
Talk about a missed opportunity.
It reminds me of the short story ''"Descent of Species"'' in the interesting [[collection ("Sum") by David Eagleman|Sum by David Eagleman]].
But, here is something on a more serious note [[and on good questions|Good questions - from a consciousness perspective]], as well as about [[Inquiring about what we don't know]].
Wisdom is hereditary - You get it from your children.
I love the depth, sensitivity, humility, wisdom, humor, and Menschlichkeit^^1^^ of Wislawa Szymborska.
Here are a few things from [[her Nobel Prize lecture|http://www.nobelprize.org/nobel_prizes/literature/laureates/1996/szymborska-lecture.html]]. Really a poem of a lecture :)
She starts off, plain and simple:
>They say the first sentence in any speech is always the hardest. Well, that one's behind me, anyway.
and adds
>my lecture will be rather short. All imperfection is easier to tolerate if served up in small doses.
And why will it be short (and imperfect)? Because she was asked to talk about poetry (!) and from past experience, she observes:
>I've said very little on the subject, next to nothing, in fact. And whenever I have said anything, I've always had the sneaking suspicion that I'm not very good at it.
Szymborska freely admits that she finds it hard to explain what inspiration is:
>It's just not easy to explain something to someone else that you don't understand yourself.
(BTW, this kind of logic didn't prevent many others, mind you, from trying to "explain" things they don't understand. Or as Johann Wolfgang von Geothe observed: When ideas fail, words come in very handy.)
But, with her typical sense of keen observation and wisdom, she comes up with an inspiring description:
>inspiration is not the exclusive privilege of poets or artists generally. There is, has been, and will always be a certain group of people whom inspiration visits. It's made up of all those who've consciously chosen their calling and do their job with love and imagination. It may include doctors, teachers, gardeners - and I could list a hundred more professions. Their work becomes one continuous adventure as long as they manage to keep discovering new challenges in it. Difficulties and setbacks never quell their curiosity. A swarm of new questions emerges from every problem they solve. Whatever inspiration is, it's born from a continuous "I don't know." ^^2^^
She has a healthy (and based on past/historic experience) suspicion of people like dictators, fanatics and demagogues. She acknowledges their "inspiration" and zeal springing from strong convictions:
>they too perform their duties with inventive fervor. Well, yes, but they "know." They know, and whatever they know is enough for them once and for all.
(or as [[Alain (Emile Chartier)|https://en.wikipedia.org/wiki/%C3%89mile_Chartier]] observed: Nothing is more dangerous than an idea, when it is the only idea we have.
She states that "any knowledge that doesn't lead to new questions quickly dies out: it fails to maintain the temperature required for sustaining life." (or as Henry Ford had observed: "Anyone who stops learning is old, whether at twenty or eighty.")
>This is why I value that little phrase "I don't know" so highly. It's small, but it flies on mighty wings. It expands our lives to include the spaces within us as well as those outer expanses in which our tiny Earth hangs suspended.
(or as Isaac Asimov put it:
>The most exciting phrase to hear in science, the one that heralds new discoveries, is not "Eureka!", but "That's funny...".)
On looking at the world with fresh/new/wondering (and optimistic) eyes, she paints a great image about her wish ([[similar to that of the poet Leah Goldberg|http://mikrarevivim.blogspot.com/2014/02/blog-post_1412.html]]) to get
>a chance to chat with the Ecclesiastes [ [[Koheleth|http://www.mechon-mamre.org/p/pt/pt3101.htm]], the son of King David], the author of that moving lament on the vanity of all human endeavors
> [הֲבֵל הֲבָלִים אָמַר קֹהֶלֶת, הֲבֵל הֲבָלִים הַכֹּל הָבֶל.]. I would bow very deeply before him, because he is, after all, one of the greatest poets, for me at least. That done, I would grab his hand. "'There's nothing new under the sun': that's what you wrote, Ecclesiastes. But you yourself were born new under the sun. And the poem you created is also new under the sun, since no one wrote it down before you. And all your readers are also new under the sun, since those who lived before you couldn't read your poem. And that cypress that you're sitting under hasn't been growing since the dawn of time. It came into being by way of another cypress similar to yours, but not exactly the same. And Ecclesiastes, I'd also like to ask you what new thing under the sun you're planning to work on now? A further supplement to the thoughts you've already expressed? Or maybe you're tempted to contradict some of them now? In your earlier work you mentioned joy - so what if it's fleeting? So maybe your new-under-the-sun poem will be about joy? Have you taken notes yet, do you have drafts? I doubt you'll say, 'I've written everything down, I've got nothing left to add.' There's no poet in the world who can say this, least of all a great poet like yourself."
Looking at the universe, ever the optimist ("planets already dead? still dead? we just don't know"), she chooses to appreciate the gift we received:
>whatever we might think of this measureless theater to which we've got reserved tickets, but tickets whose lifespan is laughably short, bounded as it is by two arbitrary dates; whatever else we might think of this world - it is astonishing.
But we are astonished, not because we compare the world we observe to a known "reference world". Again, we are not that wise, and we don't possess that kind of knowledge:
>Our astonishment exists per se and isn't based on comparison with something else.
(on which Carl Sagan had to say: Every aspect of Nature reveals a deep mystery and touches our sense of wonder and awe. Those afraid of the universe as it really is, those who pretend to nonexistent knowledge and envision a Cosmos centered on human beings will prefer the fleeting comforts of superstition. They avoid rather than confront the world. But those with the courage to explore the weave and structure of the Cosmos, even where it differs profoundly from their wishes and prejudices, will penetrate its deepest mysteries.)
----
^^1^^ Menschlichkeit - from the [[German Duden|http://www.duden.de/rechtschreibung/Menschlichkeit]]: Erbarmen, Humanität, Menschenfreundlichkeit, Milde, Toleranz. See also [[How to be a Mensch|http://judaism.about.com/od/judaismbasics/a/howtobeamensch.htm]].
^^2^^ Richard Feynman was [[captured on video|http://www.youtube.com/watch?v=E1RqTP5Unr4&feature=fvwrel]] talking about the same state of "not knowing":
>You see, one thing is, I can live with doubt and uncertainty and not knowing^^3^^. I think it's much more interesting to live not knowing than to have answers which might be wrong. I have approximate answers and possible beliefs and different degrees of certainty about different things, but I am not absolutely sure of anything and there are many things I do not know anything about, such as whether it means anything to ask 'why we are here?' and what the question might mean. I might think about it a little bit if and if I can't figure it out then I go into something else. But I don't have to know an answer. I don't have ... I don't feel frightened by not knowing things, by being lost in a mysterious universe without having any purpose, which is the way it really is as far as I can tell, possibly. It doesn't frighten me.
^^3^^ - and according to Terry Pratchett, [[even DEATH can try to believe in it|THE UNCERTAINTY PRINICIPLE - according to Sir Terry]]
We are a wordy species. ''Words are the wings both intellect and imagination fly on.'' Music, dance, visual arts, crafts of all kinds, all are central to human development and well-being, and no art or skill is ever useless learning; but to train the mind to take off from immediate reality and return to it with new understanding and new strength, nothing quite equals poem and story.
In an interesting [[article of that name in the New Yorker|http://www.newyorker.com/magazine/2015/11/23/writers-in-the-storm]], Kathryn Schultz reviews "How weather went from symbol to science and back again".
She is pointing out that weather maintained "maintain[ed] its centrality in Western literature for millennia":
>Storms sent to punish, lightning to frighten, thunder to humble, floods to obliterate: across nearly all cultures, the first stories that we told about weather were efforts to explain it, and the explanations invariably came down to divine agency. From the bag of winds gifted to Aeolus to the Biblical drought visited on Jerusalem, meteorological phenomena first appear in the narrative record as tools used by deities to battle one another and to help or hinder humans.
But,
>in the mid-seventeenth century, the role of weather in literature was shifting. While our earliest weather stories tried to explain meteorological phenomena, subsequent ones used meteorological phenomena to explain ourselves. Weather, in other words, went from being mythical to being metaphorical. In a symbolic system that is now so familiar as to be intuitive, atmospheric conditions came to stand in for the human condition.
Schultz mentions the book //Weatherland// by Alexandra Harris, which is a history of weather in English literature.
>“My subject is not the weather itself,” she writes, “but the weather as it is daily recreated in the human imagination.” Her survey begins with an astute observation: weather works so well as a symbol partly because its literal manifestation is oddly slippery. “Meteorological phenomena are serially elusive,” she writes.
>Weather, one of the most potent forces in our lives, is often imperceptible, perpetually changing, and frequently mysterious.
>As Harris points out, all of this makes it a convenient substitute for another “serially elusive” phenomenon: the self. King Lear, Shakespeare tells us, was “minded like the weather”—as charged and turbulent as the storm that raged around him on the heath. In a way, we have all been minded like the weather ever since, so accustomed have we become to using meteorology to describe mental activity. Minds are foggy (unless they are experiencing a brainstorm), temperaments sunny, attitudes chilly; moods blow in and out. Wordsworth wandered lonely as a cloud; Robert Frost, in “Tree at My Window,” explicitly compared outer and inner weather.
Then, there was a change in the literary positioning of weather ("the weather has turned"? :)
John Ruskin, the most influential critic in the nineteenth century, in 1856, observed that:
>The sun does not shine mercilessly, Ruskin insisted, and the skies have never once wept, and, Dickens notwithstanding, fog cannot be found “cruelly pinching the toes and fingers” of a little apprentice boy. “It is one of the signs of the highest power in a writer,” Ruskin argued, “to check all such habits of thought, and to keep his eyes fixed firmly on the pure fact ”—on the “ordinary, proper, and true appearance of things.”
What Ruskin wished for was that the society of meteorologists In England) will establish
> its influence and its power to be omnipotent over the globe, so that it may be able to know, at any given instant, the state of the atmosphere at every point on its surface.”
>It would take the better part of a century, but that vision eventually became a reality. What Ruskin did not predict, however (though it might have pleased him), was that the rise of an empirical model of weather would occasion the decline of the symbolic one—and, with it, the over-all decline of weather in literature.
Schultz summarizes the state of meteorology:
>At the dawn of the nineteenth century, then, nearly everything about weather remained a mystery. No one understood the wind. No one knew why temperatures dropped as you climbed closer to the sun. No one could explain how clouds, with their countless tons of rainwater, somehow remained suspended in midair. No one knew what caused lightning, or why it tended to strike the tallest thing around—a problem for Christian meteorology, since it appeared that God had a special propensity for destroying church steeples. No one even knew what the sky was made of. Above all, no one knew what it was likely to do next.
A gap between meteorology and literature started to open up:
>Meteorology had constructed a new story about weather, down to the vocabulary used to tell it, yet writers seemed unable or unwilling to make use of it, even as their traditional strategies were becoming less viable. With the rise of a scientific understanding of weather, both its mythological and metaphorical clout diminished. Storms seem less like the verdict of God when you can track them by satellite two weeks out, and lightning loses some of its gothic thrill when you know that it is merely electrostatic discharge. A forecast [...] insists that the weather is the product of natural forces, utterly unrelated to the goings on in our culture, our relationships, and our soul.
As Western Civilization shifted from rural living to urban dwelling and working, and from older modes of locomotion to cars and trucks, the weather and forecasting it became less crucial.
And so, literature also became "climate-controlled".
But today, with climate change (or "global warming" if you are so politically inclined to call it), weather is starting to regain prominence, in multiple domains, including literature.
It seems like "a circle is closing" (or maybe it's a spiral overlapping):
>These days, the atmosphere really does reflect human activity, and, as in our most ancient stories, our own behavior really is bringing disastrous weather down on our heads. Meteorological activity, so long yoked to morality, finally has genuine ethical stakes.
Starting in the twentieth century, authors started writing works classified as "cli-fi" (a play on "sci-fi"), as well as dystopian novels, where the climate is in crisis ^^1^^.
The situation looks bleak:
>Today, it is, if anything, even more difficult to imagine an end of the world that is not driven by a change in the weather. We speak of a “nuclear winter,” of the firestorms and the radical temperature drop that would follow an asteroid strike, of global climate change nudging planetary temperatures out of the range of the habitable.
Schultz ends her piece with a call to leverage writers writing about weather and thus "changing the narrative" (again) to spur us to take the situation seriously and do something about it, so that reality does not resemble fiction (sci-, cli- or otherwise, with respect to the weather):
>But apocalyptic stories are ultimately escapist fantasies, even if no one escapes. End-times narratives offer the terrible resolution of ultimate destruction. Partial destruction, displacement, hunger, want, weakness, loss, need—these are more difficult stories. That is all the more reason we should be glad writers are beginning to tell them: to help us imagine not dying this way but living this way. To weather something is, after all, to survive.
----
^^1^^ -
>The dystopian novelist J. G. Ballard wrote about climate change before the climate was known to be changing; later, Kim Stanley Robinson, Margaret Atwood, and many others used the conventions of science fiction to create worlds in which the climate is in crisis. More recently, though, books about weather are displaying a distinct migratory pattern—farther from genre fiction and closer to realism; backward in time from the future and ever closer to the present. See, among others, Ian McEwan’s “Solar,” Barbara Kingsolver’s “Flight Behavior,” Nathaniel Rich’s “Odds Against Tomorrow,” Karen Walker’s “The Age of Miracles,” Jesmyn Ward’s “Salvage the Bones,” and Dave Eggers’s “Zeitoun.” (Weather is on the rise in nonfiction, too. In addition to “Weatherland” and “The Weather Experiment,” recent or forthcoming titles include Tim Flannery’s “Atmosphere of Hope,” Christine Corton’s “London Fog,” Lauren Redniss’s “Thunder & Lightning,” and Cynthia Barnett’s “Rain.”)
I think that [[Joseph Weizenbaum|https://en.wikipedia.org/wiki/Joseph_Weizenbaum]] (of the AI [[ELIZA program|https://cse.buffalo.edu/~rapaport/572/S02/weizenbaum.eliza.1966.pdf]] fame (see [[Joseph Weizenbaum on ELIZA]])), in the following snippet, starts by expressing some limitation of programming/writing for understanding, but later (it seems) changes his mind, and appears to agree with [[Alan Perlis about knowledge acquisition through programming|You think you KNOW when you learn, are more sure when you can write, even more when you can teach, but certain when you can program.]]. I personally think that programming can be a very powerful tool/means for understanding, but it is not necessary (i.e., deep understanding doesn't //require// coding and/or programming skills) nor sufficient (i.e., programming something is not //guaranteeing// deep understanding). Coding something can (and should) be an opportunity to analyze, abstract, define, recreate, explore, experiment, and tinker -- all of which are known to help humans gain deep(er) understanding and knowledge. >To understand something sufficiently well to be able to program it for a computer does not mean to understand it to its ultimate depth. There can be no such ultimate understanding in practical affairs. Programming is rather a test of understanding. In this respect it is like writing; often when we think we understand something and attempt to write about it, our very act of composition reveals our lack of understanding even to ourselves. Our pen writes the word 'because' and suddenly stops. We thought we understood the 'why' of something, but discover that we don't. We begin a sentence with 'obviously,' and then see that what we meant to write is not obvious at all. Sometimes we connect two clauses with the word 'therefore,' only to then see that our chain of reasoning is defective. > >Programming is like that. It is, after all, writing, too. But in ordinary writing we sometimes obscure our lack of understanding, our failures in logic, by unwittingly appealing to the immense flexibility of a natural language and to its inherent ambiguity...[and, I'd like to add: to the intelligence and life context of the reader]. >An interpreter of programming-language-texts, a computer, is immune to the seductive influence of mere eloquence... A computer is a merciless critic. :: -- Source : ''Weizenbaum's book'' [[Computer Power and Human Reason: From Judgment to Calculation|http://blogs.evergreen.edu/cpat/files/2013/05/Computer-Power-and-Human-Reason.pdf]]. :: (see [[John McCarthy's criticism|http://jmc.stanford.edu/artificial-intelligence/reviews/weizenbaum.pdf]] of ''Weizenbaum's book''). From an article titled [["Writing is a Technology that Restructures Thought"|http://worrydream.com/refs/Ong%20-%20Writing%20is%20a%20Technology%20that%20Restructures%20Thought.pdf]] by Walter J. Ong: >To say writing is artificial is not to condemn it but to praise it. Like other artificial creations and indeed more than any other, writing is utterly invaluable and indeed essential for the realization of fuller, interior, human potentials. Technologies are not mere exterior aids but also interior transformations of consciousness, and never more than when they affect the word. Such transformations of consciousness can be uplifting, at the same time that they are in a sense alienating. By distancing thought, alienating it from its original habitat in sounded words, writing raises consciousness. Alienation from a natural milieu can be good for us and indeed is in many ways essential for fuller human life. ''To live and to understand fully, we need not only proximity but also distance.'' This writing provides for, thereby accelerating the evolution of consciousness as nothing else before it does.
You don't want a million answers as much as you want a few forever questions. The questions are diamonds you hold in the light. Study a lifetime and you see different colors from the same jewel.
You think you KNOW when you learn, are more sure when you can write, even more when you can teach, but certain when you can program. (see [[Joseph Weizenbaum on Writing and programming for understanding|Writing and programming for understanding]]).
From a book review titled [["Improve Your Life by Paying Attention"|https://fs.blog/2013/10/improve-your-life-by-paying-attention/]] in [[Farnam Street|https://fs.blog/]], reviewing Winifred Gallagher's book //Rapt: Attention and the Focused Life//: >That your experience largely depends on the material objects and mental subjects that you choose to pay attention to or ignore is not an imaginative notion, but a physiological fact. When you focus on a stop sign or a sonnet, a waft of perfume or a stock-market tip, your brain registers that “target,” which enables it to affect your behavior. In contrast, the things that you don’t attend to in a sense don’t exist, at least for you. > >All day long, you are selectively paying attention to something, and much more often than you may suspect, you can take charge of this process to good effect. Indeed, your ability to focus on this and suppress that is the key to controlling your experience and, ultimately, your well-being. which echos (but expresses an even more radical effect) William James who said: >My experience is what I agree to attend to, and only those things which I notice shape my mind. Winifred also point out (ha!): >Like fingers pointing to the moon, other diverse disciplines from anthropology to education, behavioral economics to family counseling similarly suggest that the skillful management of attention is the sine qua non of the good life and the key to improving virtually every aspect of your experience, from mood to productivity to relationships.
In his book //Zen Physics// David Darling expresses the following thoughts about understanding through language, models, and intuition: >Zen uses language to point beyond language, which is what poets and playwrights and musicians do. But, less obvious, it is also what modern science does if the intuitive leap is taken beyond its abstract formalism. The deep, latent message of quantum mechanics, for instance, codified in the language of mathematics, is that there is a reality beyond our senses which eludes verbal comprehension or logical analysis. And this is best exemplified in the central idea of "complimentarity" -- an idea introduced by Niels Bohr to account for the fact that two different conditions of observations could lead to conclusions that were //conceptually// incompatible. > >In one experiment, for example, light might behave as if it were made of particles, in another as if it were made of waves. Bohr proposed, however, there is no //intrinsic// incompatibility between these results because they are functions of different conditions of observations; no experiment could be devised that would demonstrate both aspects of a single condition. > >The wave and particle natures of light and matter are not mutually exclusive, they are mutually inclusive -- necessary, complimentary aspects of reality. Bohr gained his inspiration for this concept from Eastern philosophy, in particular from the Taoist concept of the dynamic interplay of opposites, //yin// and //yang//. And so, one of the central principles of modern physics is coincident with, and actually derived from, one of the most basic doctrines of the Eastern worldview. And as far as the [[intuitive leap|It's about Big Meaning, not Big Data.]] goes: >Intuition has ever been the handmaid of science. And although science presents its theories and conclusions in a "respectable" symbolic form, its greatest advances have always come initially not from the application of reason but from intuitive leaps -- sudden flashes of inspiration very much akin to Zen experiences.